{"record":{"id":"f8c402284ac0d8cb","repo":"Hmbown/CodeWhale","slug":"siliconflow-china-api-key-not-found-get-a-key","errorCode":null,"errorMessage":"SiliconFlow China API key not found. Get a key: {}. Run 'codewhale auth set --provider siliconflow-CN', set {}, or add [{}] api_key in ~/.codewhale/config.toml. [providers.siliconflow] remains a fallback when the CN table omits api_key.","messagePattern":"SiliconFlow China API key not found\\. Get a key: (.+?)\\. Run 'codewhale auth set --provider siliconflow-CN', set (.+?), or add \\[(.+?)\\] api_key in ~/\\.codewhale/config\\.toml\\. \\[providers\\.siliconflow\\] remains a fallback when the CN table omits api_key\\.","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/config.rs","lineNumber":6368,"sourceCode":"        }\n\n        match provider {\n            ApiProvider::Deepseek | ApiProvider::DeepseekCN => anyhow::bail!(\n                \"DeepSeek API key not found.\\n\\\n                 \\n\\\n                 1. Get a key:  https://platform.deepseek.com/api_keys\\n\\\n                 2. Save it (works in every folder, no OS prompts):\\n\\\n                        codewhale auth set --provider deepseek\\n\\\n                 \\n\\\n                 Alternatives:\\n\\\n                   • export DEEPSEEK_API_KEY=<your-key>      (current shell only;\\n\\\n                     also note: zsh users — exports in ~/.zshrc only reach interactive\\n\\\n                     shells, prefer ~/.zshenv for everything)\\n\\\n                   • api_key = \\\"<your-key>\\\"  in ~/.codewhale/config.toml\\n\\\n                   • already configured DeepSeek Harness? grant read-only access:\\n\\\n                        codewhale auth external-consent --provider deepseek --mode read-only\"\n            ),\n            ApiProvider::SiliconflowCn => anyhow::bail!(\n                \"SiliconFlow China API key not found. Get a key: {}. Run 'codewhale auth set --provider siliconflow-CN', \\\n                 set {}, or add [{}] api_key in ~/.codewhale/config.toml. \\\n                 [providers.siliconflow] remains a fallback when the CN table omits api_key.\",\n                provider\n                    .credential_url()\n                    .unwrap_or(\"https://cloud.siliconflow.com/account/ak\"),\n                provider.env_vars_label(),\n                provider_config_table_name(provider)?\n            ),\n            ApiProvider::Moonshot => {\n                let credential_help =\n                    credential_help_for_provider_route(provider, &self.deepseek_base_url());\n                if moonshot_base_url_is_exact_kimi_code(&self.deepseek_base_url()) {\n                    anyhow::bail!(\n                        \"Kimi Code membership-plan API key not found. Get a plan key: {}. This route uses api.kimi.com/coding/v1 and does not import Kimi CLI credentials. Run 'codewhale auth set --provider moonshot', set {}, or add [{}] api_key.\",\n                        credential_help\n                            .credential_url\n                            .unwrap_or(KIMI_CODE_MEMBERSHIP_PLAN_CONSOLE_URL),","sourceCodeStart":6350,"sourceCodeEnd":6386,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/config.rs#L6350-L6386","documentation":"Raised for ApiProvider::SiliconflowCn when no credential exists for the China route. The CN route has its own auth store entry, env var, and [providers.siliconflow-CN] table; the generic [providers.siliconflow] table still works as a fallback when the CN table omits api_key. The message interpolates the credential URL, env-var label, and table name.","triggerScenarios":"provider = siliconflow-CN with none of: auth store key, the CN env var, [providers.siliconflow-CN] api_key, or a fallback [providers.siliconflow] api_key.","commonSituations":"Users switching between siliconflow and siliconflow-CN assuming credentials are shared; regional accounts with separate keys; missing CN-specific secret in CI.","solutions":["Run codewhale auth set --provider siliconflow-CN.","Or export the CN env var shown in the message.","Or add api_key under [providers.siliconflow-CN] in ~/.codewhale/config.toml.","Or rely on the fallback: keep api_key in [providers.siliconflow] and omit it from the CN table."],"exampleFix":"# before\nprovider = \"siliconflow-CN\"\n# no key anywhere\n\n# after\n[providers.siliconflow-CN]\napi_key = \"sk-...\"\n# or terminal: codewhale auth set --provider siliconflow-CN","handlingStrategy":"validation","validationCode":"fn siliconflow_cn_key_present(cfg: &Config) -> bool {\n    let cn = cfg.provider_config_for(ApiProvider::SiliconflowCn);\n    let fallback = cfg.provider_config_for(ApiProvider::Siliconflow);\n    cn.as_ref().and_then(|p| p.api_key.as_ref()).is_some()\n        || fallback.and_then(|p| p.api_key).is_some()\n        || env_nonempty(\"SILICONFLOW_CN_API_KEY\") || env_nonempty(\"SILICONFLOW_API_KEY\")\n        || secret_store_has(ApiProvider::SiliconflowCn)\n}\n\nanyhow::ensure!(siliconflow_cn_key_present(&config), \"configure siliconflow-CN auth\");","typeGuard":"fn siliconflow_cn_credentials_configured(cfg: &Config) -> bool {\n    siliconflow_cn_key_present(cfg)\n}","tryCatchPattern":"match config.deepseek_api_key() {\n    Err(e) if e.to_string().starts_with(\"SiliconFlow China API key not found\") => {\n        run_auth_set(ApiProvider::SiliconflowCn)?; // then retry resolution once\n        config.deepseek_api_key()\n    }\n    other => other,\n}","preventionTips":["Treat siliconflow and siliconflow-CN as separate credential identities.","If you run both, set api_key in [providers.siliconflow] so the CN table can fall back to it.","Store region-specific secrets separately in CI."],"tags":["rust","siliconflow","api-key","authentication","regional","config"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}