Unwrapping one level at a time reveals the chain of context around an error.

Unwrap Chain

unwrap_chain.go
package main

import (
	"errors"
	"fmt"
)

func main() {
	var step = 
	base := errors.New("invalid value")
	first := fmt.Errorf("%s failed: %w", step, base)
	second := fmt.Errorf("request failed: %w", first)
	next := errors.Unwrap(second)
	root := errors.Unwrap(next)

	fmt.Println("step=", step)
	fmt.Println("outer=", second.Error())
	fmt.Println("next=", next.Error())
	fmt.Println("root=", root.Error())
}
package main

import (
	"errors"
	"fmt"
)

func main() {
	var step = 
	base := errors.New("invalid value")
	first := fmt.Errorf("%s failed: %w", step, base)
	second := fmt.Errorf("request failed: %w", first)
	next := errors.Unwrap(second)
	root := errors.Unwrap(next)

	fmt.Println("step=", step)
	fmt.Println("outer=", second.Error())
	fmt.Println("next=", next.Error())
	fmt.Println("root=", root.Error())
}
package main

import (
	"errors"
	"fmt"
)

func main() {
	var step = 
	base := errors.New("invalid value")
	first := fmt.Errorf("%s failed: %w", step, base)
	second := fmt.Errorf("request failed: %w", first)
	next := errors.Unwrap(second)
	root := errors.Unwrap(next)

	fmt.Println("step=", step)
	fmt.Println("outer=", second.Error())
	fmt.Println("next=", next.Error())
	fmt.Println("root=", root.Error())
}
unwrap `errors.Unwrap` exposes the next error in the chain, which is useful when teaching how wrapping stores causes.