{"record":{"id":"4779e13fe2ca5af4","repo":"Hmbown/CodeWhale","slug":"legacy-deepseek-home-error-wrapped-as-io-errorkind-notfound","errorCode":null,"errorMessage":"(legacy_deepseek_home error wrapped as io::ErrorKind::NotFound)","messagePattern":"\\(legacy_deepseek_home error wrapped as io::ErrorKind::NotFound\\)","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/session_manager.rs","lineNumber":2926,"sourceCode":"        }\n        Err(err) => {\n            tracing::warn!(\n                target: \"session::migration\",\n                \"Could not copy legacy sessions into {}: {err}\",\n                dir.display()\n            );\n        }\n    }\n    Ok(dir)\n}\n\nfn merge_missing_legacy_session_entries(primary: &Path) -> io::Result<usize> {\n    if codewhale_paths::codewhale_home_is_explicit() {\n        return Ok(0);\n    }\n\n    let legacy = codewhale_config::legacy_deepseek_home()\n        .map_err(|e| io::Error::new(io::ErrorKind::NotFound, e.to_string()))?\n        .join(\"sessions\");\n    if !legacy.is_dir() || paths_equivalent(primary, &legacy) {\n        return Ok(0);\n    }\n\n    copy_missing_dir_entries(&legacy, primary)\n}\n\nfn copy_missing_dir_entries(src: &Path, dst: &Path) -> io::Result<usize> {\n    fs::create_dir_all(dst)?;\n    let mut copied = 0;\n    for entry in fs::read_dir(src)? {\n        let entry = entry?;\n        let source = entry.path();\n        let target = dst.join(entry.file_name());\n\n        let file_type = entry.file_type()?;\n        if file_type.is_dir() {","sourceCodeStart":2908,"sourceCodeEnd":2944,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/session_manager.rs#L2908-L2944","documentation":"merge_missing_legacy_session_entries resolves the legacy ~/.deepseek home via codewhale_config::legacy_deepseek_home() to migrate old session files into the primary sessions dir. If that resolution fails, the error is rewrapped as io::ErrorKind::NotFound.","triggerScenarios":"Opening the default sessions dir when codewhale_home_is_explicit() is false (legacy migration active) and legacy_deepseek_home() cannot determine the legacy home (typically HOME unavailable).","commonSituations":"Headless/service environments without HOME where the legacy-migration path still runs; partially cleaned-up legacy directories.","solutions":["Set CODEWHALE_HOME explicitly so the legacy-migration path is skipped (codewhale_home_is_explicit returns true).","Ensure HOME is set so the legacy path can be resolved.","If legacy data is not needed, confirm migration is complete and rely on the explicit-home setting going forward."],"exampleFix":"// before: service without HOME, legacy migration fails\nExecStart=/usr/bin/codewhale\n// after\nEnvironment=CODEWHALE_HOME=/var/lib/codewhale\nExecStart=/usr/bin/codewhale","handlingStrategy":"fallback","validationCode":"if std::env::var_os(\"CODEWHALE_HOME\").is_none() && std::env::var_os(\"HOME\").is_none() { eprintln!(\"set CODEWHALE_HOME to skip legacy migration\"); }","typeGuard":null,"tryCatchPattern":"// legacy home resolution is internal; guard the entry point\nmatch default_sessions_dir() {\n    Err(e) if e.kind() == io::ErrorKind::NotFound && e.to_string().contains(\"deepseek\") => {\n        std::env::set_var(\"CODEWHALE_HOME\", fallback_dir);\n        default_sessions_dir()?\n    }\n    r => r?,\n}","preventionTips":["Set CODEWHALE_HOME explicitly so the legacy migration path is bypassed","Complete the ~/.deepseek -> ~/.codewhale migration once, then remove legacy dirs","Ensure HOME is present in service definitions"],"tags":["migration","sessions-dir","legacy-path"],"backgroundTag":"directory-not-found","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}