{"record":{"id":"6558e322ab27e7af","repo":"sigoden/aichat","slug":"no-user-s-config-directory","errorCode":null,"errorMessage":"No user's config directory","messagePattern":"No user's config directory","errorType":"panic","errorClass":"Panic","httpStatus":null,"severity":"critical","filePath":"src/config/mod.rs","lineNumber":295,"sourceCode":"            config.setup_model()?;\n            config.setup_document_loaders();\n            config.setup_user_agent();\n            Ok(())\n        };\n        let ret = setup(&mut config);\n        if !info_flag {\n            ret?;\n        }\n        Ok(config)\n    }\n\n    pub fn config_dir() -> PathBuf {\n        if let Ok(v) = env::var(get_env_name(\"config_dir\")) {\n            PathBuf::from(v)\n        } else if let Ok(v) = env::var(\"XDG_CONFIG_HOME\") {\n            PathBuf::from(v).join(env!(\"CARGO_CRATE_NAME\"))\n        } else {\n            let dir = dirs::config_dir().expect(\"No user's config directory\");\n            dir.join(env!(\"CARGO_CRATE_NAME\"))\n        }\n    }\n\n    pub fn local_path(name: &str) -> PathBuf {\n        Self::config_dir().join(name)\n    }\n\n    pub fn config_file() -> PathBuf {\n        match env::var(get_env_name(\"config_file\")) {\n            Ok(value) => PathBuf::from(value),\n            Err(_) => Self::local_path(CONFIG_FILE_NAME),\n        }\n    }\n\n    pub fn roles_dir() -> PathBuf {\n        match env::var(get_env_name(\"roles_dir\")) {\n            Ok(value) => PathBuf::from(value),","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/config/mod.rs#L277-L313","documentation":"`config_dir` resolves the application's config directory from (1) an env-var override, (2) `XDG_CONFIG_HOME`, and finally (3) the `dirs` crate's `config_dir()`, which it unwraps with `.expect(\"No user's config directory\")`. On platforms where the OS cannot supply a user config directory (e.g. $HOME unset on Linux, missing profile on Windows), this panics with that message rather than returning an error.","triggerScenarios":"Calling `config_dir()`/`local_path()`/any config-loading entry point on a system where `dirs::config_dir()` returns None — typically Linux/Unix with `$HOME` unset or pointing to a nonexistent user, or a stripped container without `/home`.","commonSituations":"Running the CLI as a systemd service or cron job without HOME set; Docker containers running as a uid with no passwd entry; broken `$HOME` after user migration; Windows roaming-profile failures.","solutions":["Set `XDG_CONFIG_HOME` (or the app's config_dir env override) to a writable directory before running.","Ensure `HOME` is set to an existing, readable directory for the process user.","In containers/services, run as a user that exists in /etc/passwd with a home directory.","Patch the call site to replace `.expect` with graceful fallback (e.g. `./` or temp dir) and a clear error instead of a panic."],"exampleFix":"// before\nenv::set_var(\"HOME\", \"\"); // in service environment\n// after\n// in the service unit or shell:\n// Environment=HOME=/home/app  (or XDG_CONFIG_HOME=/etc/app)\n// or in code:\nif dirs::config_dir().is_none() {\n    std::env::set_var(\"XDG_CONFIG_HOME\", \"/tmp\");\n}","handlingStrategy":"validation","validationCode":"fn config_env_ready() -> Result<(), String> {\n    if std::env::var_os(\"XDG_CONFIG_HOME\").is_some()\n        || std::env::var_os(\"HOME\").map(|h| std::path::Path::new(&h).is_dir()).unwrap_or(false)\n    {\n        Ok(())\n    } else {\n        Err(\"set XDG_CONFIG_HOME or a valid HOME; otherwise config_dir() panics\".into())\n    }\n}","typeGuard":null,"tryCatchPattern":"// the failure is a panic, not an error — guard before first config access\nmatch std::panic::catch_unwind(|| config::local_path(\"settings.json\")) {\n    Ok(p) => load(p),\n    Err(_) => {\n        eprintln!(\"No user config directory: set XDG_CONFIG_HOME or HOME\");\n        std::process::exit(78); // EX_CONFIG\n    }\n}","preventionTips":["Always set XDG_CONFIG_HOME (or the app's config-dir env override) in services, cron, and containers.","Ensure the runtime user has a valid HOME directory that exists.","Run containers with a real passwd entry (useradd) rather than bare --user 1000.","Wrap early config access in catch_unwind or patch .expect into a graceful fallback."],"tags":["configuration","filesystem","environment","panic"],"backgroundTag":"directory-not-found","analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}