wtfutil/wtf · error
get %v from %v: %w
Error message
get %v from %v: %w
What it means
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.
Source
Thrown at cfg/secrets.go:157
}
}
// Fetch secret for `service`. Service is customarily a URL, but can be any
// identifier uniquely used by wtf to identify the service, such as the name
// of the module. nil is returned if the secretStore global property is not
// present or the secret is not found in that store.
func FetchSecret(globalConfig *config.Config, service string) (*Secret, error) {
prog := newProgram(globalConfig)
if prog == nil {
// No secret store configured.
return nil, nil
}
cred, err := client.Get(prog.runner, service)
if err != nil {
return nil, fmt.Errorf("get %v from %v: %w", service, prog.store, err)
}
return &Secret{
Service: cred.ServerURL,
Secret: cred.Secret,
Username: cred.Username,
Store: prog.store,
}, nil
}
func StoreSecret(globalConfig *config.Config, secret *Secret) error {
prog := newProgram(globalConfig)
if prog == nil {
return errors.New("cannot store secrets: wtf.secretStore is not configured")
}
cred := &credentials.Credentials{View on GitHub (pinned to bb838c1ccb)
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
Example fix
// before
secret, err := cfg.FetchSecret(conf, &cfg.Secret{Service: "Grafana"})
// after
secret, err := cfg.FetchSecret(conf, &cfg.Secret{Service: "grafana"}) // match stored label exactly
if err != nil {
log.Fatalf("secret store problem: %v", err) // inspect wrapped cause
} Defensive patterns
Strategy: try-catch
Validate before calling
if !secretStoreConfigured(conf) {
return errors.New("secret store not configured")
}
if secret.Service == "" {
return errors.New("service label required")
} Try / catch
secret, err := cfg.FetchSecret(conf, svc)
if err != nil {
var cause error
if errors.Unwrap(err) != nil {
cause = errors.Unwrap(err)
}
log.Printf("fetch %q failed: %v (cause: %v)", svc.Service, err, cause)
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- store %v: %w
- cannot store secrets: wtf.secretStore is not configured
- failed to convert username %s to account ID: %v
- invalid app index selected
- cannot expand user-specific home dir
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/81b71f4f3d492f97.
Report an issue: GitHub.