{"record":{"id":"f754c957018ee6f1","repo":"jlcodes99/cockpit-tools","slug":"token","errorCode":null,"errorMessage":"未找到有效 Token {:?}","messagePattern":"未找到有效 Token (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cockpit-core/src/modules/codex_account_core_mutations_quota.rs","lineNumber":57,"sourceCode":"        let parsed: serde_json::Value = match serde_json::from_str(&content) {\n            Ok(v) => v,\n            Err(e) => {\n                logger::log_warn(&format!(\n                    \"Codex 文件旧规则 JSON 解析失败，将尝试 Token/JSON 导入逻辑 {:?}: {}\",\n                    file_path, e\n                ));\n                fallback_files.push((content, filename_label));\n                continue;\n            }\n        };\n\n        let before_count = candidates.len();\n        match &parsed {\n            serde_json::Value::Object(_) => {\n                if let Some((tokens, hint)) = extract_codex_tokens_from_value(&parsed) {\n                    candidates.push((tokens, hint, filename_label.clone()));\n                } else {\n                    logger::log_error(&format!(\"未找到有效 Token {:?}\", file_path));\n                }\n            }\n            serde_json::Value::Array(arr) => {\n                for item in arr {\n                    if let Some((tokens, hint)) = extract_codex_tokens_from_value(item) {\n                        let label = item\n                            .get(\"email\")\n                            .and_then(|v| v.as_str())\n                            .unwrap_or(&filename_label)\n                            .to_string();\n                        candidates.push((tokens, hint, label));\n                    }\n                }\n            }\n            _ => {\n                logger::log_error(&format!(\"不支持的 JSON 格式 {:?}\", file_path));\n            }\n        }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/crates/cockpit-core/src/modules/codex_account_core_mutations_quota.rs#L39-L75","documentation":"During import_from_files, a JSON file parsed as a top-level object was inspected by extract_codex_tokens_from_value, which looks for known Codex token fields (accessToken/access_token, id_token + access_token, or refresh_token). When none of these token keys are found in the object, this error is logged and the file falls back to the Token/JSON import logic. It means the file is valid JSON but lacks the credential fields the importer recognizes.","triggerScenarios":"Calling import_from_files with a JSON file whose top-level is an object but which contains none of accessToken, access_token, id_token+access_token, or refresh_token — e.g. an auth.json that only has OPENAI_API_KEY, or a config/settings JSON dropped in by mistake.","commonSituations":"Users hand-edit auth.json and delete the tokens; importing a Codex config.json or settings file instead of auth.json; provider version changes renamed token fields; copying an empty or partially-written auth file.","solutions":["Open the file and confirm it contains at least one of accessToken/access_token, id_token+access_token, or refresh_token","Re-authenticate with the Codex CLI so auth.json is regenerated with valid tokens","Verify you are importing the auth file, not a config or settings file","Check for renamed key casing (accessToken vs access_token) depending on CLI version"],"exampleFix":"// before (auth.json)\n{ \"OPENAI_API_KEY\": \"sk-...\" }\n// after\n{ \"tokens\": { \"id_token\": \"...\", \"access_token\": \"...\", \"refresh_token\": \"...\" } }","handlingStrategy":"validation","validationCode":"fn has_codex_tokens(v: &serde_json::Value) -> bool {\n    let obj = match v { serde_json::Value::Object(o) => o, _ => return false };\n    obj.contains_key(\"accessToken\") || obj.contains_key(\"access_token\")\n        || obj.contains_key(\"refresh_token\")\n        || (obj.contains_key(\"id_token\") && obj.contains_key(\"access_token\"))\n}\n// call before import: if !has_codex_tokens(&parsed) { fix file first }","typeGuard":"fn is_json_object(v: &serde_json::Value) -> bool {\n    matches!(v, serde_json::Value::Object(_))\n}","tryCatchPattern":null,"preventionTips":["Keep auth.json produced by the Codex CLI intact; never hand-edit out token fields","Validate JSON token keys before running batch imports","Distinguish auth files from config/settings files by name before import","After provider/CLI upgrades, re-verify the exported schema"],"tags":["codex","import","validation","json"],"backgroundTag":"codex-import-token-not-found","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}