moonD4rk/HackBrowserData · error

%s: %w

Error message

%s: %w

What it means

NewMasterKeys iterates the configured key retrievers and wraps each retriever failure as "<retriever-name>: <underlying error>". It collects every failure with errors.Join so all retriever errors are surfaced together instead of failing fast on the first one. Seeing this error means at least one named retriever could not produce a master key.

Source

Thrown at masterkey/masterkeys.go:47

func NewMasterKeys(r Retrievers, hints Hints) (MasterKeys, error) {
	var keys MasterKeys
	var errs []error

	for _, t := range []struct {
		name string
		r    Retriever
		dst  *[]byte
	}{
		{"v10", r.V10, &keys.V10},
		{"v11", r.V11, &keys.V11},
		{"v20", r.V20, &keys.V20},
	} {
		if t.r == nil {
			continue
		}
		k, err := t.r.RetrieveKey(hints)
		if err != nil {
			errs = append(errs, fmt.Errorf("%s: %w", t.name, err))
			continue
		}
		*t.dst = k
	}
	return keys, errors.Join(errs...)
}

View on GitHub (pinned to 0503d04d7a)

Solutions

  1. Read the wrapped inner error to identify which retriever (by t.name) failed and why
  2. Fix the underlying retriever configuration (password, credentials, storage name in Hints)
  3. If a retriever is unusable, remove it or pass nil so it is skipped — nil retrievers are silently skipped
  4. Log the joined error with errors.Is/As per wrapped cause to branch on specific failures

Example fix

// before
keys, err := masterkey.NewMasterKeys(hints, retrievers)
log.Fatal(err)
// after
keys, err := masterkey.NewMasterKeys(hints, retrievers)
if err != nil {
	var joined interface{ Unwrap() []error }
	if errors.As(err, &joined) {
		for _, e := range joined.Unwrap() {
			log.Printf("retriever failed: %v", e)
		}
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

for _, r := range retrievers {
	if r == nil { continue }
}

Type guard

func hasValidRetrievers(rs []masterkey.Retriever) bool {
	for _, r := range rs { if r != nil { return true } }
	return false
}

Try / catch

keys, err := masterkey.NewMasterKeys(hints, retrievers)
if err != nil {
	var joinErr interface{ Unwrap() []error }
	if errors.As(err, &joinErr) {
		for _, cause := range joinErr.Unwrap() {
			log.Printf("retriever cause: %v", cause)
		}
	}
}

Prevention

When it happens

Trigger: Calling NewMasterKeys with a retriever whose RetrieveKey(hints) returns a non-nil error; each failing retriever contributes one wrapped error, joined and returned alongside any partially filled keys.

Common situations: Misconfigured retrievers (empty keychain password, missing env var for a credential retriever), the target browser/storage not installed, or an OS-level failure such as keychain unlock denial.

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/5262b4cfffd0e6dd. Report an issue: GitHub.