{"record":{"id":"5262b4cfffd0e6dd","repo":"moonD4rk/HackBrowserData","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"masterkey/masterkeys.go","lineNumber":47,"sourceCode":"func NewMasterKeys(r Retrievers, hints Hints) (MasterKeys, error) {\n\tvar keys MasterKeys\n\tvar errs []error\n\n\tfor _, t := range []struct {\n\t\tname string\n\t\tr    Retriever\n\t\tdst  *[]byte\n\t}{\n\t\t{\"v10\", r.V10, &keys.V10},\n\t\t{\"v11\", r.V11, &keys.V11},\n\t\t{\"v20\", r.V20, &keys.V20},\n\t} {\n\t\tif t.r == nil {\n\t\t\tcontinue\n\t\t}\n\t\tk, err := t.r.RetrieveKey(hints)\n\t\tif err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"%s: %w\", t.name, err))\n\t\t\tcontinue\n\t\t}\n\t\t*t.dst = k\n\t}\n\treturn keys, errors.Join(errs...)\n}\n","sourceCodeStart":29,"sourceCodeEnd":54,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/masterkey/masterkeys.go#L29-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped inner error to identify which retriever (by t.name) failed and why","Fix the underlying retriever configuration (password, credentials, storage name in Hints)","If a retriever is unusable, remove it or pass nil so it is skipped — nil retrievers are silently skipped","Log the joined error with errors.Is/As per wrapped cause to branch on specific failures"],"exampleFix":"// before\nkeys, err := masterkey.NewMasterKeys(hints, retrievers)\nlog.Fatal(err)\n// after\nkeys, err := masterkey.NewMasterKeys(hints, retrievers)\nif err != nil {\n\tvar joined interface{ Unwrap() []error }\n\tif errors.As(err, &joined) {\n\t\tfor _, e := range joined.Unwrap() {\n\t\t\tlog.Printf(\"retriever failed: %v\", e)\n\t\t}\n\t}\n}","handlingStrategy":"try-catch","validationCode":"for _, r := range retrievers {\n\tif r == nil { continue }\n}","typeGuard":"func hasValidRetrievers(rs []masterkey.Retriever) bool {\n\tfor _, r := range rs { if r != nil { return true } }\n\treturn false\n}","tryCatchPattern":"keys, err := masterkey.NewMasterKeys(hints, retrievers)\nif err != nil {\n\tvar joinErr interface{ Unwrap() []error }\n\tif errors.As(err, &joinErr) {\n\t\tfor _, cause := range joinErr.Unwrap() {\n\t\t\tlog.Printf(\"retriever cause: %v\", cause)\n\t\t}\n\t}\n}","preventionTips":["Pass nil for retrievers you cannot configure so they are skipped","Validate retriever config (passwords, paths) before constructing NewMasterKeys","Log each wrapped cause individually instead of the joined blob"],"tags":["go","error-wrapping","key-retrieval","errors-join"],"backgroundTag":"api-request-failed","analyzedSha":"0503d04d7a8d0379d060268a74f1b149e5a0aad5","analyzedAt":"2026-09-06T13:38:28.707Z","contentChangedAt":"2026-09-06T13:38:28.707Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}