jlcodes99/cockpit-tools · error
Codex 导入失败 {}: {}
Error message
Codex 导入失败 {}: {} What it means
Per-file Codex account import failure log emitted inside import_from_files (src-tauri/src/modules/codex_account_mutations_quota.rs:142). When upsert_account_with_hints fails for one credential file and the error is NOT a disk-full condition, the label (file name/email) and underlying error are logged and the file is appended to the `failed` list; the import of remaining files continues. It is a non-fatal, per-account failure, not an abort of the whole batch.
Source
Thrown at src-tauri/src/modules/codex_account_mutations_quota.rs:142
}
logger::log_info(&format!("Codex 导入成功: {}", account.email));
imported.push(account);
}
Err(e) => {
if is_disk_full_error_message(&e) {
logger::log_error(&format!(
"Codex 导入因磁盘空间不足终止: label={}, imported={}, error={}",
label,
imported.len(),
e
));
return Err(format!(
"磁盘空间不足,已终止导入(已成功 {} 个)。{}",
imported.len(),
e
));
}
logger::log_error(&format!("Codex 导入失败 {}: {}", label, e));
failed.push(CodexFileImportFailure {
email: label,
error: e,
});
}
}
}
for (content, label, auth_file_plan_type) in fallback_files {
progress_index += 1;
if let Some(app_handle) = crate::get_app_handle() {
use tauri::Emitter;
let _ = app_handle.emit(
"codex:file-import-progress",
serde_json::json!({
"current": progress_index,
"total": total,
"email": &label,View on GitHub (pinned to 1ed8b77992)
Solutions
- Inspect the per-file error text logged next to the label to see why upsert_account_with_hints rejected the token file
- Re-export or re-login that account in Codex CLI to obtain a fresh valid auth file (containing access_token/id_token or refresh_token) and re-import
- Check that the file is valid JSON with the expected token keys before importing
- If storage is implicated but not detected as disk-full, verify free space and write permissions on the app data directory
- Collect results from the returned failed list (CodexFileImportFailure) instead of expecting the whole call to fail
Example fix
// before: blind bulk import of every file in a folder
import_from_files(paths).await?;
// after: pre-validate JSON token keys and skip invalid files
for p in paths {
let content = fs::read_to_string(&p)?;
let ok = serde_json::from_str::<serde_json::Value>(&content)
.map(|v| v.get("access_token").is_some()
|| v.get("accessToken").is_some()
|| v.get("refresh_token").is_some())
.unwrap_or(false);
if !ok { log::warn!("skipping invalid token file: {}", p.display()); continue; }
} Defensive patterns
Strategy: validation
Validate before calling
fn is_importable_codex_file(path: &Path) -> bool {
std::fs::read_to_string(path).ok()
.and_then(|c| serde_json::from_str::<serde_json::Value>(&c).ok())
.map(|v| v.get("access_token").is_some()
|| v.get("accessToken").is_some()
|| v.get("refresh_token").is_some())
.unwrap_or(false)
} Type guard
fn has_valid_tokens(v: &serde_json::Value) -> bool {
v.get("access_token").and_then(|t| t.as_str()).map(|s| !s.is_empty()).unwrap_or(false)
|| v.get("refresh_token").and_then(|t| t.as_str()).map(|s| !s.is_empty()).unwrap_or(false)
} Try / catch
match import_from_files(paths).await {
Ok(result) => {
for f in &result.failed { // Vec<CodexFileImportFailure>
eprintln!("账号 {} 导入失败: {}", f.email, f.error);
}
}
Err(e) => eprintln!("导入中止: {e}"),
} Prevention
- Pre-validate every auth file for the required token keys before calling import_from_files
- Keep auth files in their original format; do not hand-edit or redact token fields
- Re-export auth files from the same Codex CLI version used for import
- Treat the returned `failed` list as the source of truth for which accounts need attention
When it happens
Trigger: Calling import_from_files with old-format candidate files where upsert_account_with_hints(tokens, account_id_hint, None) returns Err — e.g. a token file missing accessToken/access_token/id_token/refresh_token fields, malformed JSON, an account_id_hint that conflicts with stored data, or a storage write error that is not disk-full.
Common situations: Bulk-importing a directory of auth JSON files where some are stale, hand-edited, truncated, or from an incompatible Codex CLI version; duplicate email labels colliding with existing accounts; corrupted files copied from another machine.
Related errors
- messages.rawLineNoRefreshToken(item.lineNumber)
- messages.rawLineMultipleRefreshTokens(item.lineNumber)
- 未找到有效 Token {:?}
- 不支持的 JSON 格式 {:?}
- 磁盘空间不足,已终止导入(已成功 {} 个)。{}
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/63840addeeb59f9d.
Report an issue: GitHub.