There are a number of `errorx` functions that rely on `Cast` implementation. `Cast` was designed in pre Go 1.13 times and it doesn't respect wrap semantic of Go 1.13. While I'm not sure whether `Cast` should respect it, but I'm pretty sure that functions like `HasTrait`, `Ignore`, `IgnoreWithTrait`, `ExtractProperty` and probably `TraitSwitch` and `TypeSwitch` should. There are more places using `Cast`: 1. `(ErrorBuilder).WithCause(error)`, `(ErrorBuilder).EnhanceStackTrace()` and `(ErrorBuilder).assembleStackTrace()`. Should it know about wrap? Probably yes. 2. `(*Error).Is(target error)`. Should we accept that `target` could be a wrapped `*errorx.Error`. I am personally not sure here. Standard library implementations don't unwrap `target` which is an argument to stick to current behaviour. 3. `(*Error).Property(Property)`. Should it work when underlying property is buried under non-errorx wrapper? Looks like it should. But I then see that `Property` being a method is a wrong abstraction. Should we hide the method in favor to `ExtractProperty`? 4. `errorx.GetTypeName(error)`. I'm not sure what would be the least surprising behaviour but the following example definitely looks broken: https://play.golang.org/p/_UAGbNO2ZlH There also is a `errorx.WithPayload` which accepts `*errorx.Error` as an argument. To call this function the client code have to cast `error` to `*errorx.Error` with something like `errorx.Cast`. Should we change `errorx.WithPayload` to accept `error`? Also there are a lot of `Cast` usages in our private codebase that will benefit from `Cast` being wrap-aware. Whooa, that was a lot of concerns. Should I split them to separate issues? Maybe, but let's discuss them first.