jlcodes99/cockpit-tools · critical
无法获取用户目录
Error message
无法获取用户目录
What it means
get_old_codex_data_dir resolves the legacy Codex data directory via dirs::data_local_dir(), falling back to dirs::home_dir().expect("无法获取用户目录"). If both the local data dir and the home dir are unavailable it panics. It is used only by migrate_codex_data_if_needed for one-time migration.
Source
Thrown at crates/cockpit-core/src/modules/codex_account_core_provider.rs:887
// built-in `openai` provider with this account's own base URL and auth.json API key.
let builtin_openai_config = resolve_api_provider_config(
provider_config.base_url.as_deref(),
Some(CodexApiProviderMode::OpenaiBuiltin),
None,
None,
)?;
write_api_provider_to_config_toml(base_dir, &builtin_openai_config)
}
/// 旧版数据目录(~/Library/Application Support/com.antigravity.cockpit-tools/)
fn get_old_codex_data_dir() -> PathBuf {
#[cfg(test)]
if let Some(data_dir) = std::env::var_os("COCKPIT_TOOLS_DATA_DIR") {
return PathBuf::from(data_dir).join("legacy-codex-data");
}
dirs::data_local_dir()
.unwrap_or_else(|| dirs::home_dir().expect("无法获取用户目录"))
.join("com.antigravity.cockpit-tools")
}
/// 将旧目录中的 codex 数据迁移到新目录(一次性,迁移成功后删除旧文件)
fn migrate_codex_data_if_needed(new_data_dir: &PathBuf) {
#[cfg(test)]
if std::env::var_os("COCKPIT_TOOLS_DATA_DIR").is_some() {
// Test guards use an explicit data root; never migrate the user's legacy files.
return;
}
let old_dir = get_old_codex_data_dir();
if !old_dir.exists() {
return;
}
// 迁移 codex_accounts.json
let old_index = old_dir.join("codex_accounts.json");View on GitHub (pinned to 1ed8b77992)
Solutions
- Set HOME (Unix) or USERPROFILE/LOCALAPPDATA (Windows) so dirs can resolve a path.
- Set COCKPIT_TOOLS_DATA_DIR (test builds) to bypass legacy-dir resolution.
- Skip migration when no home directory can be resolved — migration is optional one-time work.
- Run the app under a normal user account with a profile rather than a bare service account.
Example fix
// before
migrate_codex_data_if_needed(&data_dir); // panics without HOME
// after
if std::env::var_os("HOME").is_some()
|| std::env::var_os("USERPROFILE").is_some()
{
migrate_codex_data_if_needed(&data_dir);
} else {
eprintln!("no home dir; skipping legacy migration");
} Defensive patterns
Strategy: validation
Validate before calling
fn legacy_migration_env_ok() -> bool {
std::env::var_os("COCKPIT_TOOLS_DATA_DIR").is_some()
|| std::env::var_os("HOME").is_some()
|| std::env::var_os("USERPROFILE").is_some()
} Try / catch
std::panic::catch_unwind(get_old_codex_data_dir).map_err(|_| anyhow::anyhow!("无法获取用户目录")) Prevention
- Skip legacy migration when no home directory can be resolved — it is optional one-time work
- Set COCKPIT_TOOLS_DATA_DIR in test environments to isolate storage
- Set HOME/LOCALAPPDATA in CI containers before running migration paths
- Run migration only inside an interactive user session
When it happens
Trigger: Calling migrate_codex_data_if_needed (which calls get_old_codex_data_dir) on a system where dirs::data_local_dir() and dirs::home_dir() both return None — no XDG/USERPROFILE environment and no resolvable home.
Common situations: Test/CI environments with a stripped environment (COCKPIT_TOOLS_DATA_DIR unset and no HOME); running under a service account without a profile; broken passwd/XDG configuration.
Related errors
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/b61978b68ddea7b7.
Report an issue: GitHub.