{"record":{"id":"3755dd6fa4d70179","repo":"Hmbown/CodeWhale","slug":"external-credential-access-for-is-dormant-until","errorCode":null,"errorMessage":"external credential access for {} is dormant until that provider is explicitly selected","messagePattern":"external credential access for (.+?) is dormant until that provider is explicitly selected","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":6914,"sourceCode":"            })\n    }\n\n    /// Mint a read capability for the exact external credential path selected\n    /// when consent was granted.\n    ///\n    /// Path resolution itself is side-effect free. The returned capability is\n    /// required by every external credential adapter before it may stat or\n    /// read the selected file. `suggested_path` is used only in disabled-mode\n    /// guidance; an existing grant remains pinned to its persisted path even\n    /// if ambient CLI-home environment variables change later.\n    pub(crate) fn external_credential_read_grant(\n        &self,\n        provider: ApiProvider,\n        source: codewhale_config::ExternalCredentialSource,\n        suggested_path: &Path,\n    ) -> Result<codewhale_config::ExternalCredentialReadGrant> {\n        if provider != self.api_provider() {\n            anyhow::bail!(\n                \"external credential access for {} is dormant until that provider is explicitly selected\",\n                provider.display_name()\n            );\n        }\n        let kind = provider\n            .metadata()\n            .map(codewhale_config::provider::Provider::kind)\n            .context(\"external credentials are unsupported for this provider\")?;\n        let consent = self\n            .provider_config_for(provider)\n            .and_then(|entry| entry.external_credentials.as_ref())\n            .with_context(|| {\n                format!(\n                    \"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 {}\",\n                    source.as_str(),\n                    provider.display_name(),\n                    kind.as_str(),\n                    codewhale_config::quote_os_path(suggested_path)","sourceCodeStart":6896,"sourceCodeEnd":6932,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/config.rs#L6896-L6932","documentation":"External credential import (e.g. reading a credential from another tool's keychain/file) is gated on the provider it belongs to being the currently selected `api_provider`. If a caller requests an external credential grant for a provider that is not active, the access is refused as 'dormant' — the credential would be read but never used, so the read is denied rather than performed.","triggerScenarios":"Calling the external-credential grant method (`Result<ExternalCredentialReadGrant>` helper at config.rs:6914) with `provider` whose value differs from `self.api_provider()`.","commonSituations":"Running an auth-import/onboarding flow while a different provider is selected in config; a session where the user switched `api_provider` after starting the import; scripts that import credentials for several providers in one run without switching the active provider between them.","solutions":["Set the provider you are importing credentials for as the active `api_provider` in config, then retry the import.","Only request the external credential grant for `self.api_provider()`'s value — gate the call on that equality.","If you need credentials for multiple providers, import each one in a run where that provider is selected."],"exampleFix":"// before\nlet grant = cfg.external_credential_grant(ApiProvider::Google, source, &path)?; // active is openai\n\n// after\nif provider == cfg.api_provider() {\n    let grant = cfg.external_credential_grant(provider, source, &path)?;\n}","handlingStrategy":"validation","validationCode":"if provider != config.api_provider() {\n    eprintln!(\"skipping external credential import for {provider:?}: not the active provider\");\n    return;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check `api_provider` before starting any external credential import flow.","Import credentials for one provider per session with that provider selected.","After switching providers, re-run onboarding rather than reusing a prior import attempt."],"tags":["credentials","auth","provider"],"backgroundTag":"missing-credentials","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}