jlcodes99/cockpit-tools · error
未找到有效 Token {:?}
Error message
未找到有效 Token {:?} What it means
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.
Source
Thrown at crates/cockpit-core/src/modules/codex_account_core_mutations_quota.rs:57
let parsed: serde_json::Value = match serde_json::from_str(&content) {
Ok(v) => v,
Err(e) => {
logger::log_warn(&format!(
"Codex 文件旧规则 JSON 解析失败,将尝试 Token/JSON 导入逻辑 {:?}: {}",
file_path, e
));
fallback_files.push((content, filename_label));
continue;
}
};
let before_count = candidates.len();
match &parsed {
serde_json::Value::Object(_) => {
if let Some((tokens, hint)) = extract_codex_tokens_from_value(&parsed) {
candidates.push((tokens, hint, filename_label.clone()));
} else {
logger::log_error(&format!("未找到有效 Token {:?}", file_path));
}
}
serde_json::Value::Array(arr) => {
for item in arr {
if let Some((tokens, hint)) = extract_codex_tokens_from_value(item) {
let label = item
.get("email")
.and_then(|v| v.as_str())
.unwrap_or(&filename_label)
.to_string();
candidates.push((tokens, hint, label));
}
}
}
_ => {
logger::log_error(&format!("不支持的 JSON 格式 {:?}", file_path));
}
}View on GitHub (pinned to 1ed8b77992)
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
Example fix
// before (auth.json)
{ "OPENAI_API_KEY": "sk-..." }
// after
{ "tokens": { "id_token": "...", "access_token": "...", "refresh_token": "..." } } Defensive patterns
Strategy: validation
Validate before calling
fn has_codex_tokens(v: &serde_json::Value) -> bool {
let obj = match v { serde_json::Value::Object(o) => o, _ => return false };
obj.contains_key("accessToken") || obj.contains_key("access_token")
|| obj.contains_key("refresh_token")
|| (obj.contains_key("id_token") && obj.contains_key("access_token"))
}
// call before import: if !has_codex_tokens(&parsed) { fix file first } Type guard
fn is_json_object(v: &serde_json::Value) -> bool {
matches!(v, serde_json::Value::Object(_))
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- 不支持的 JSON 格式 {:?}
- invalidJsonMessage
- messages.rawLineNoRefreshToken(item.lineNumber)
- messages.rawLineMultipleRefreshTokens(item.lineNumber)
- messages.invalidJson
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/f754c957018ee6f1.
Report an issue: GitHub.