{"record":{"id":"5998aef482cfca0f","repo":"Hmbown/CodeWhale","slug":"no-usable-runtime-effective-api-key","errorCode":null,"errorMessage":"no usable runtime-effective API key","messagePattern":"no usable runtime-effective API key","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/credential_handoff.rs","lineNumber":55,"sourceCode":"    let source = resolved.api_key_source;\n    if source != Some(RuntimeApiKeySource::Cli) {\n        if provider == ProviderKind::OpenaiCodex {\n            bail!(\"bearer credentials are not an API key\");\n        }\n        let uses_api_key = provider != ProviderKind::Xai\n            || xai_auth_diagnostics(store, runtime_overrides).evaluates_runtime_api_key();\n        ensure!(uses_api_key, \"OAuth bearer credentials are not an API key\");\n        let kimi_bearer = provider == ProviderKind::Moonshot\n            && resolved\n                .auth_mode\n                .as_deref()\n                .is_some_and(auth_mode_uses_kimi_imported_token);\n        ensure!(!kimi_bearer, \"bearer credentials are not an API key\");\n    }\n    ensure!(source.is_some(), \"no runtime-effective API key\");\n    resolved\n        .api_key\n        .filter(|value| !value.trim().is_empty())\n        .context(\"no usable runtime-effective API key\")\n}\n\npub(crate) fn handoff_secret_line(\n    writer: &mut impl Write,\n    stdout_is_terminal: bool,\n    resolve: impl FnOnce() -> Result<String>,\n) -> Result<()> {\n    prepare_stdout(stdout_is_terminal)?;\n    let secret = Zeroizing::new(resolve().map_err(|_| anyhow::anyhow!(\"unavailable credential\"))?);\n    ensure!(!secret.trim().is_empty(), \"credential handoff was empty\");\n    let written = writeln!(writer, \"{}\", secret.as_str());\n    if written.is_ok() || written.is_err_and(|error| error.kind() == ErrorKind::BrokenPipe) {\n        return Ok(());\n    }\n    bail!(\"credential handoff could not write to stdout\")\n}\n#[cfg(test)]","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/cli/src/credential_handoff.rs#L37-L73","documentation":"After confirming a credential source exists, `resolve_api_key` unwraps `resolved.api_key`, filtering out whitespace-only/empty values, and attaches this context if it is None or blank. So a source was recorded but the actual key string is missing or empty — an inconsistency between credential metadata and the stored value.","triggerScenarios":"The secret store entry or config key exists but holds an empty/whitespace string; a key was deleted or truncated but its source marker remains; an override set the key to `\"\"`.","commonSituations":"Partially completed setup where the user saved an empty key; secret-store corruption or a failed write; templated config where the key placeholder wasn't substituted; env var set to empty string.","solutions":["Re-enter the API key via the provider's key setup command so the stored value is non-empty.","Delete the stale/empty credential entry and set it fresh.","Check for an empty env-var override (e.g. `PROVIDER_API_KEY=\"\"`) and unset it.","Inspect the secret store/config for the provider slot and confirm the stored value length."],"exampleFix":"// before\nexport OPENROUTER_API_KEY=\"\"   # source exists, value empty\ncodewhale handoff openrouter\n// after\nunset OPENROUTER_API_KEY\ncodewhale auth set openrouter sk-or-...","handlingStrategy":"validation","validationCode":"// Re-set the key if the stored value is blank\nif stored_key.trim().is_empty() { codewhale auth set <provider> <new-key>; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never save empty/placeholder keys during setup; validate non-empty before storing","Audit config templates so ${KEY} placeholders get substituted","Unset (don't empty) env-var overrides that should not apply"],"tags":["credentials","api-key","empty-string","secrets","rust"],"backgroundTag":"missing-api-key","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}