{"record":{"id":"81b71f4f3d492f97","repo":"wtfutil/wtf","slug":"get-v-from-v-w","errorCode":null,"errorMessage":"get %v from %v: %w","messagePattern":"get (.+?) from (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cfg/secrets.go","lineNumber":157,"sourceCode":"\t}\n}\n\n// Fetch secret for `service`. Service is customarily a URL, but can be any\n// identifier uniquely used by wtf to identify the service, such as the name\n// of the module.  nil is returned if the secretStore global property is not\n// present or the secret is not found in that store.\nfunc FetchSecret(globalConfig *config.Config, service string) (*Secret, error) {\n\tprog := newProgram(globalConfig)\n\n\tif prog == nil {\n\t\t// No secret store configured.\n\t\treturn nil, nil\n\t}\n\n\tcred, err := client.Get(prog.runner, service)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get %v from %v: %w\", service, prog.store, err)\n\t}\n\n\treturn &Secret{\n\t\tService:  cred.ServerURL,\n\t\tSecret:   cred.Secret,\n\t\tUsername: cred.Username,\n\t\tStore:    prog.store,\n\t}, nil\n}\n\nfunc StoreSecret(globalConfig *config.Config, secret *Secret) error {\n\tprog := newProgram(globalConfig)\n\n\tif prog == nil {\n\t\treturn errors.New(\"cannot store secrets: wtf.secretStore is not configured\")\n\t}\n\n\tcred := &credentials.Credentials{","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/cfg/secrets.go#L139-L175","documentation":"FetchSecret retrieves a credential from the configured secret store via client.Get(prog.runner, service). If the underlying store program (pass, security CLI, etc.) fails to return the credential, the error is wrapped as 'get <service> from <store>: <cause>'. This is a wrapper — the actionable cause is the inner error.","triggerScenarios":"Requesting a secret whose service/username entry does not exist in the store; the store backend binary missing or failing (e.g. keychain locked, gpg agent unavailable); wrong service name casing; the runner (command) failing with a nonzero exit.","commonSituations":"Keychain/Keyring locked after reboot; 'pass' store not initialized (no GPG key configured); secret created under a different service label than the module requests; headless servers without the secret-store CLI installed.","solutions":["Read the wrapped cause after 'from <store>:' and fix that condition first","Verify the secret exists in the store (e.g. `pass show <service>` or open Keychain Access)","Initialize/set up the store backend (gpg key for pass, unlock keychain, install the CLI)","Confirm the service/username strings in the module config exactly match the stored entry"],"exampleFix":"// before\nsecret, err := cfg.FetchSecret(conf, &cfg.Secret{Service: \"Grafana\"})\n// after\nsecret, err := cfg.FetchSecret(conf, &cfg.Secret{Service: \"grafana\"}) // match stored label exactly\nif err != nil {\n    log.Fatalf(\"secret store problem: %v\", err) // inspect wrapped cause\n}","handlingStrategy":"try-catch","validationCode":"if !secretStoreConfigured(conf) {\n    return errors.New(\"secret store not configured\")\n}\nif secret.Service == \"\" {\n    return errors.New(\"service label required\")\n}","typeGuard":null,"tryCatchPattern":"secret, err := cfg.FetchSecret(conf, svc)\nif err != nil {\n    var cause error\n    if errors.Unwrap(err) != nil {\n        cause = errors.Unwrap(err)\n    }\n    log.Printf(\"fetch %q failed: %v (cause: %v)\", svc.Service, err, cause)\n    return err\n}","preventionTips":["Keep service labels consistent between storing and fetching code","Unwrap the %w cause to find the real store failure","Test the store CLI manually with the same user","Initialize the pass/keychain backend before first run"],"tags":["go","secrets","error-wrapping"],"backgroundTag":"secret-store-lookup-failed","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}