gastownhall/beads · error
credential source %s: %w
Error message
credential source %s: %w
What it means
ResolveLadder walks configured credential sources in order; if a source that reports itself as configured returns an error, the ladder fails closed and wraps the error with the source's name. This distinguishes 'source misconfigured/broken' from 'source not configured', so the caller gets a definitive failure instead of silently falling through.
Source
Thrown at internal/creds/creds.go:62
// Name is the provenance slug (env var, file, or command label).
Name() string
// Resolve returns the credential when this source is configured. A
// configured=false result means "not set here, try the next rung". A non-nil
// error means "configured but failed" and aborts the walk — the ladder never
// falls through to a lower-priority rung after an error.
Resolve(ctx context.Context) (cred Credential, configured bool, err error)
}
// ResolveLadder walks sources in priority order and returns the first configured
// credential. It fails closed: any source error stops the walk and propagates, so a
// configured-but-broken helper can never silently downgrade to a lower rung. When no
// source is configured it returns configured=false with no error, letting the caller
// fall through to a driver-native default (PGPASSWORD, ~/.pgpass, and the like).
func ResolveLadder(ctx context.Context, sources ...Source) (Credential, bool, error) {
for _, s := range sources {
cred, configured, err := s.Resolve(ctx)
if err != nil {
return Credential{}, true, fmt.Errorf("credential source %s: %w", s.Name(), err)
}
if configured {
if cred.Source == "" {
cred.Source = s.Name()
}
return cred, true, nil
}
}
return Credential{}, false, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped inner error and the source name prefix to see which source failed and why.
- Fix or remove the failing source from the configured ladder (config file or env) so the ladder can fall through to later sources.
- Re-authenticate or repair the failing credential helper.
- Reorder the ladder to try a healthy source first if the broken one is optional.
Example fix
// before bd config set credential_command "gh-helper-missing" // after bd config unset credential_command # let ladder fall through to next source
Defensive patterns
Strategy: try-catch
Validate before calling
// verify each configured source before relying on the ladder
for _, s := range sources {
if _, configured, err := s.Resolve(ctx); configured && err != nil {
// repair or unset this source first
}
} Try / catch
cred, configured, err := creds.ResolveLadder(ctx, srcs...)
if err != nil {
// err text names the failing source; drop/repair it and retry
return fmt.Errorf("no usable credential: %w", err)
} Prevention
- Keep the ladder's first source healthy or unset so fall-through works.
- Test each configured source individually after credential/config changes.
- Remove stale credential_command entries after uninstalling helpers.
When it happens
Trigger: A Source's Resolve returns err != nil — e.g. the credential-command source's helper fails (1593–1597), or an env/file source fails reading — while configured=true.
Common situations: First source in the ladder (e.g. credential_command) is configured but its helper errors; stale credentials in one source poisoning resolution; a config file listing a helper that is no longer installed.
Related errors
- failed to get repos config: %w
- LoadCreateContext: read issue_prefix: %w
- LoadCreateContext: read allowed_prefixes: %w
- LoadCreateContext: read custom types: %w
- LoadCreateContext: read custom statuses: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1744b4b5a96e6a35.
Report an issue: GitHub.