Hmbown/CodeWhale · error · anyhow::Error
external credential access for {} is dormant until that prov
Error message
external credential access for {} is dormant until that provider is explicitly selected What it means
Config::external_credential_read_grant() mints the capability required before any external CLI credential file may be stat/read. It refuses when the requested provider differs from the active api_provider(): access to another CLI's credentials stays dormant until that provider is explicitly selected. This is a deliberate least-privilege gate, not a bug.
Source
Thrown at crates/tui/src/config.rs:5966
})
}
/// Mint a read capability for the exact external credential path selected
/// when consent was granted.
///
/// Path resolution itself is side-effect free. The returned capability is
/// required by every external credential adapter before it may stat or
/// read the selected file. `suggested_path` is used only in disabled-mode
/// guidance; an existing grant remains pinned to its persisted path even
/// if ambient CLI-home environment variables change later.
pub(crate) fn external_credential_read_grant(
&self,
provider: ApiProvider,
source: codewhale_config::ExternalCredentialSource,
suggested_path: &Path,
) -> Result<codewhale_config::ExternalCredentialReadGrant> {
if provider != self.api_provider() {
anyhow::bail!(
"external credential access for {} is dormant until that provider is explicitly selected",
provider.display_name()
);
}
let kind = provider
.metadata()
.map(codewhale_config::provider::Provider::kind)
.context("external credentials are unsupported for this provider")?;
let consent = self
.provider_config_for(provider)
.and_then(|entry| entry.external_credentials.as_ref())
.with_context(|| {
format!(
"External credentials owned by {} are disabled for {}. To allow read-only access to this exact file, run:\n codewhale auth external-consent --provider {} --mode read-only --path {}",
source.as_str(),
provider.display_name(),
kind.as_str(),
codewhale_config::quote_os_path(suggested_path)View on GitHub (pinned to 8880682c63)
Solutions
- Select the target provider first (provider = in config, or the --provider CLI flag) before requesting its external credentials.
- In code, skip the grant when provider != config.api_provider() instead of treating it as an error.
- If you only need to know whether consent exists, use external_credential_read_consent_configured(), which never mints a grant and never stats the file.
Example fix
// before
let grant = config.external_credential_read_grant(ApiProvider::Xai, source, &path)?;
// after
if config.api_provider() != ApiProvider::Xai {
return Ok(None); // external credentials dormant unless provider is selected
}
let grant = config.external_credential_read_grant(ApiProvider::Xai, source, &path)?; Defensive patterns
Strategy: validation
Validate before calling
// before touching external credentials, gate on the active provider
fn grant_if_active(
config: &Config,
provider: ApiProvider,
source: ExternalCredentialSource,
path: &Path,
) -> Result<Option<ExternalCredentialReadGrant>> {
if provider != config.api_provider() {
return Ok(None); // dormant by design — not an error
}
Ok(Some(config.external_credential_read_grant(provider, source, path)?))
} Type guard
fn provider_credentials_are_eligible(config: &Config, provider: ApiProvider) -> bool {
config.api_provider() == provider
} Try / catch
match config.external_credential_read_grant(provider, source, &path) {
Ok(grant) => Some(grant),
Err(e) if e.to_string().contains("dormant until that provider is explicitly selected") => {
None // expected for non-selected providers; do not surface as failure
}
Err(e) => return Err(e),
} Prevention
- Never iterate all providers minting read grants; only the selected provider is eligible.
- Use external_credential_read_consent_configured() for passive status checks — it never stats files or mints capabilities.
- In tests, set the provider before requesting grants.
When it happens
Trigger: Calling external_credential_read_grant(ApiProvider::Xai, ...) while the active provider is anthropic; provider-picker or diagnostic code probing credentials for every known provider regardless of selection.
Common situations: Bulk credential scans/status pages iterating all providers; code reused from a context where the provider was selected; tests that forget to set the provider before requesting a grant.
Related errors
- external credential consent for {}: {error}
- OpenAI Codex OAuth credentials are unavailable. Codewhale c
- xAI OAuth credentials not found. Options: 1. Run `codewhale
- parallel(): expected an array of thunks
- The Codewhale service returned a verification URL without a
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/3755dd6fa4d70179.
Report an issue: GitHub.