{"record":{"id":"ff1ef2c14fd72983","repo":"janhq/jan","slug":"failed-to-get-app-data-dir","errorCode":null,"errorMessage":"Failed to get app data dir","messagePattern":"Failed to get app data dir","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src-tauri/src/core/mcp/lockfile.rs","lineNumber":21,"sourceCode":"use std::path::PathBuf;\nuse tauri::{AppHandle, Manager, Runtime};\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct McpLockFile {\n    pub pid: u32,\n    #[serde(default)]\n    pub jan_pid: u32,\n    pub port: u16,\n    pub server_name: String,\n    pub created_at: String,\n    pub hostname: String,\n}\n\nfn get_lock_file_path<R: Runtime>(app: &AppHandle<R>, port: u16) -> PathBuf {\n    let app_data_dir = app\n        .path()\n        .app_data_dir()\n        .expect(\"Failed to get app data dir\");\n    app_data_dir.join(format!(\"mcp_lock_{}.json\", port))\n}\n\npub fn create_lock_file<R: Runtime>(\n    app: &AppHandle<R>,\n    port: u16,\n    server_name: &str,\n    pid: u32,\n) -> Result<(), String> {\n    let lock_path = get_lock_file_path(app, port);\n\n    // Ensure parent directory exists\n    if let Some(parent) = lock_path.parent() {\n        fs::create_dir_all(parent)\n            .map_err(|e| format!(\"Failed to create lock file directory: {}\", e))?;\n    }\n\n    let lock = McpLockFile {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/src-tauri/src/core/mcp/lockfile.rs#L3-L39","documentation":"This is a panic (.expect) from Tauri's app.path().app_data_dir() inside get_lock_file_path(), the helper used by create_lock_file, read_lock_file, and delete_lock_file. app_data_dir() resolves the platform data directory (XDG_DATA_HOME/app_id on Linux, %APPDATA%/app_id on Windows, ~/Library/Application Support/app_id on macOS). It fails when the OS-level directory cannot be determined.","triggerScenarios":"XDG_DATA_HOME is set to an invalid or non-absolute path on Linux. APPDATA env var is unset on Windows. Running in a sandboxed environment where the macOS app support path is restricted. The Tauri identifier/bundle ID is misconfigured, preventing path resolution.","commonSituations":"Linux containers without XDG_DATA_HOME set (defaults to ~/.local/share but HOME may be unset). Windows service accounts without a roaming profile. macOS App Sandbox misconfiguration. Missing CFBundleIdentifier in the Info.plist.","solutions":["Ensure XDG_DATA_HOME points to an absolute, writable path on Linux.","Verify the app's bundle identifier is set in tauri.conf.json identifier field.","Set HOME or USERPROFILE so the default data dir can be derived.","Replace .expect with a fallback to a known directory."],"exampleFix":"// before\nlet app_data_dir = app.path().app_data_dir().expect(\"Failed to get app data dir\");\n\n// after\nlet app_data_dir = app.path().app_data_dir().unwrap_or_else(|e| {\n    log::warn!(\"app_data_dir failed ({e}); falling back to home/.jan\");\n    dirs::home_dir().unwrap_or_default().join(\".jan\")\n});","handlingStrategy":"fallback","validationCode":"// Before lock file operations, verify the data dir is resolvable\nfn verify_app_data_dir<R: Runtime>(app: &AppHandle<R>) -> Result<PathBuf, String> {\n    app.path().app_data_dir()\n        .map_err(|e| format!(\"Cannot resolve app data dir: {e}\"))\n}\n\n// In the calling code:\nlet dir = verify_app_data_dir(app)?;\nlet lock_path = dir.join(format!(\"mcp_lock_{}.json\", port));","typeGuard":null,"tryCatchPattern":"// Replace .expect with graceful degradation\nfn get_lock_file_path<R: Runtime>(app: &AppHandle<R>, port: u16) -> Option<PathBuf> {\n    let dir = app.path().app_data_dir().ok()?;\n    Some(dir.join(format!(\"mcp_lock_{}.json\", port)))\n}","preventionTips":["Replace .expect with .ok() and propagate None up to callers that can skip lock operations.","Cache the data dir at startup so lock operations don't re-resolve it.","Ensure XDG_DATA_HOME / APPDATA / bundle ID are correctly configured.","Test MCP lock operations in a minimal container to catch env issues."],"tags":["panic","app-data-dir","mcp","lockfile","env-var"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}