moonD4rk/HackBrowserData · error

%T: %w

Error message

%T: %w

What it means

Inside the multi-retriever RetrieveKey loop, each individual retriever failure is wrapped as "%T: %w" (the retriever's concrete Go type plus the cause) before being collected. These wrapped errors are intermediate — they end up joined inside the final "all retrievers failed" error. The %T prefix tells you exactly which retriever type failed.

Source

Thrown at masterkey/retriever.go:45

// ChainRetriever tries retrievers in order, first success wins (macOS V10: gcoredump→password→security).
type ChainRetriever struct {
	retrievers []Retriever
}

func NewChain(retrievers ...Retriever) Retriever {
	return &ChainRetriever{retrievers: retrievers}
}

func (c *ChainRetriever) RetrieveKey(hints Hints) ([]byte, error) {
	var errs []error
	for _, r := range c.retrievers {
		key, err := r.RetrieveKey(hints)
		if err == nil && len(key) > 0 {
			return key, nil
		}
		if err != nil {
			log.Debugf("retriever %T failed: %v", r, err)
			errs = append(errs, fmt.Errorf("%T: %w", r, err))
		}
	}
	return nil, fmt.Errorf("all retrievers failed: %w", errors.Join(errs...))
}

View on GitHub (pinned to 0503d04d7a)

Solutions

  1. Inspect the %T prefix in the joined error to identify the failing retriever type
  2. Fix the root cause carried in the wrapped error (see the innermost message)
  3. Remove or reorder the failing retriever if another retriever can supply the key
  4. Enable debug logging to see per-retriever failures as they happen

Example fix

// before
retrievers := []Retriever{NewFileRetriever("")}
// after
path := "key.bin"
if _, err := os.Stat(path); err != nil {
	log.Fatalf("retriever file missing: %v", err)
}
retrievers := []Retriever{NewFileRetriever(path)}
Defensive patterns

Strategy: try-catch

Validate before calling

if len(retrievers) == 0 {
	return errors.New("no retrievers configured")
}

Type guard

func isRetrieverError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "retrievers failed")
}

Try / catch

key, err := r.RetrieveKey(hints)
if err != nil {
	log.Printf("retriever %T failed: %v", r, err)
	key, err = fallback.RetrieveKey(hints)
}

Prevention

When it happens

Trigger: Any retriever in the chain returning an error from RetrieveKey(hints); the error is logged at debug level and appended to errs for the final join.

Common situations: A KeychainPasswordRetriever with an empty password, a FileRetriever pointing at a missing file, or a platform retriever hitting a command/exec failure.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06). Data as JSON: /api/errors/482d04eb11563ab4. Report an issue: GitHub.