{"record":{"id":"44d5d255dbb0da84","repo":"moonD4rk/HackBrowserData","slug":"keychain-password-not-provided","errorCode":null,"errorMessage":"keychain password not provided","messagePattern":"keychain password not provided","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"masterkey/retriever_darwin.go","lineNumber":90,"sourceCode":"\t\t\treturn darwinParams.deriveKey(rec.Password), nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"%q: %w\", storage, errStorageNotFound)\n}\n\n// KeychainPasswordRetriever unlocks login.keychain-db with the macOS login password (no root).\n// Records are cached once and reused across browsers.\ntype KeychainPasswordRetriever struct {\n\tPassword string\n\n\tonce    sync.Once\n\trecords []keychainbreaker.GenericPassword\n\terr     error\n}\n\nfunc (r *KeychainPasswordRetriever) RetrieveKey(hints Hints) ([]byte, error) {\n\tif r.Password == \"\" {\n\t\treturn nil, fmt.Errorf(\"keychain password not provided\")\n\t}\n\n\tr.once.Do(func() {\n\t\tr.records, r.err = loadKeychainRecords(r.Password)\n\t})\n\tif r.err != nil {\n\t\treturn nil, r.err\n\t}\n\n\treturn findStorageKey(r.records, hints.KeychainLabel)\n}\n\n// SecurityCmdRetriever queries Keychain via the macOS `security` CLI (may prompt). Results are\n// cached per storage name so each browser's key is fetched once.\ntype SecurityCmdRetriever struct {\n\tmu    sync.Mutex\n\tcache map[string]securityResult\n}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/masterkey/retriever_darwin.go#L72-L108","documentation":"KeychainPasswordRetriever.RetrieveKey requires the login password to unlock the keychain; when r.Password is the empty string it returns \"keychain password not provided\" immediately, before any keychain access or caching. This is a configuration/validation guard, not an OS failure.","triggerScenarios":"Constructing KeychainPasswordRetriever without setting Password (zero value struct or Password: \"\") and calling RetrieveKey.","commonSituations":"Forgot to populate the struct field, expected the library to prompt for the password (it doesn't), or the password comes from a config/env source that was empty.","solutions":["Set the Password field to the macOS user's login password before calling RetrieveKey","Load the password from a secure source (env var, prompt) and validate it's non-empty","Use a different retriever if the login password is unavailable"],"exampleFix":"// before\nr := &masterkey.KeychainPasswordRetriever{}\nkey, err := r.RetrieveKey(hints)\n// after\npw := os.Getenv(\"LOGIN_PASSWORD\")\nif pw == \"\" {\n\treturn nil, errors.New(\"LOGIN_PASSWORD env var required for keychain retriever\")\n}\nr := &masterkey.KeychainPasswordRetriever{Password: pw}\nkey, err := r.RetrieveKey(hints)","handlingStrategy":"validation","validationCode":"if retriever.Password == \"\" {\n\treturn errors.New(\"KeychainPasswordRetriever.Password must be set\")\n}","typeGuard":"func keychainRetrieverReady(r *masterkey.KeychainPasswordRetriever) bool {\n\treturn r != nil && r.Password != \"\"\n}","tryCatchPattern":"key, err := r.RetrieveKey(hints)\nif err != nil && strings.Contains(err.Error(), \"password not provided\") {\n\treturn nil, errors.New(\"configure the login password before keychain retrieval\")\n}","preventionTips":["Always populate Password at construction time","Validate non-empty credentials before building the retriever","Prefer loading the password from env/prompt over hardcoded zero-value structs"],"tags":["macos","keychain","missing-argument","config"],"backgroundTag":"missing-required-argument","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"}