Hmbown/CodeWhale · error

external credential consent path for

Error message

external credential consent path for {} must be absolute

What it means

Thrown by `ExternalCredentialConsentToml::validate_read_scope` when the consent record's stored `path` is not an absolute filesystem path. Consent is bound to a specific absolute credential file path; relative paths would make the grant ambiguous depending on the process working directory.

Solutions

  1. Fix the consent record's `path` to the fully expanded absolute path (no `~`, no relative segments).
  2. Revoke the consent and re-consent so the path is captured as absolute.
  3. Expand `~` / env vars before writing any consent record programmatically.

Example fix

// before (consent TOML)
path = "~/.codewhale/creds/google.json"
// after
path = "/home/alice/.codewhale/creds/google.json"
Defensive patterns

Strategy: validation

Validate before calling

fn is_absolute_path(p: &std::path::Path) -> bool {
    p.is_absolute()
}
// call before writing/accepting a consent record:
// assert!(is_absolute_path(&consent.path));

Try / catch

match store.read_grant(provider, source, &path) {
    Err(e) if e.to_string().contains("must be absolute") => {
        // rewrite the consent record with the expanded absolute path, then retry
        let abs = expand_tilde_and_env(&consent.path);
        fix_consent_path(provider, abs)?;
    }
    other => other,
}

Prevention

When it happens

Trigger: A consent record was created (or hand-written into the TOML) with a relative path like `~/.config/creds` (unexpanded) or `creds/token.json` instead of an absolute path.

Common situations: User hand-edited the consent file with `~` unexpanded or a relative path; a tool that wrote the consent used a non-canonicalized path; migrating config between machines with different layouts.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/d773e15a3eb83a5e. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/external_credentials.rs:396

                self.consent_version
            );
        }
        if self.provider != provider.as_str() {
            bail!(
                "external credential consent is scoped to provider {:?}, not {}",
                self.provider,
                provider.as_str()
            );
        }
        if self.source != source {
            bail!(
                "external credential consent source mismatch for {} (expected {})",
                provider.as_str(),
                source.as_str()
            );
        }
        if !self.path.is_absolute() {
            bail!(
                "external credential consent path for {} must be absolute",
                provider.as_str()
            );
        }
        let normalized = resolve_external_credential_path(&self.path)?;
        if normalized != self.path {
            bail!(
                "external credential consent path for {} must be lexically normalized: {}",
                provider.as_str(),
                quote_os_path(&self.path)
            );
        }
        if self.path != resolved_path {
            bail!(
                "external credential path changed for {}; consent covers {}, current path is {}",
                provider.as_str(),
                quote_os_path(&self.path),
                quote_os_path(resolved_path)

View on GitHub (pinned to 73e0f67d83)