`fmt.Errorf` with `%w` wraps an inner error inside an outer one, preserving the chain. Callers can use `errors.Is` / `errors.As` to inspect any level of the chain.
Sentinel errors are package-level singletons you can compare against with `errors.Is`. Use sparingly — they're part of your package's API surface and changing them is a breaking change.
Go 1.20+ ships `errors.Join`, which combines multiple errors into one. Stop accumulating errors in a slice and stringifying yourself — use the standard library.