Hmbown/CodeWhale · warning · std::io::Error

(legacy_deepseek_home error wrapped as…

Error message

(legacy_deepseek_home error wrapped as io::ErrorKind::NotFound)

What it means

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.

Solutions

  1. Set CODEWHALE_HOME explicitly so the legacy-migration path is skipped (codewhale_home_is_explicit returns true).
  2. Ensure HOME is set so the legacy path can be resolved.
  3. If legacy data is not needed, confirm migration is complete and rely on the explicit-home setting going forward.

Example fix

// before: service without HOME, legacy migration fails
ExecStart=/usr/bin/codewhale
// after
Environment=CODEWHALE_HOME=/var/lib/codewhale
ExecStart=/usr/bin/codewhale
Defensive patterns

Strategy: fallback

Validate before calling

if std::env::var_os("CODEWHALE_HOME").is_none() && std::env::var_os("HOME").is_none() { eprintln!("set CODEWHALE_HOME to skip legacy migration"); }

Try / catch

// legacy home resolution is internal; guard the entry point
match default_sessions_dir() {
    Err(e) if e.kind() == io::ErrorKind::NotFound && e.to_string().contains("deepseek") => {
        std::env::set_var("CODEWHALE_HOME", fallback_dir);
        default_sessions_dir()?
    }
    r => r?,
}

Prevention

When it happens

Trigger: 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).

Common situations: Headless/service environments without HOME where the legacy-migration path still runs; partially cleaned-up legacy directories.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/4779e13fe2ca5af4. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_manager.rs:2926

        }
        Err(err) => {
            tracing::warn!(
                target: "session::migration",
                "Could not copy legacy sessions into {}: {err}",
                dir.display()
            );
        }
    }
    Ok(dir)
}

fn merge_missing_legacy_session_entries(primary: &Path) -> io::Result<usize> {
    if codewhale_paths::codewhale_home_is_explicit() {
        return Ok(0);
    }

    let legacy = codewhale_config::legacy_deepseek_home()
        .map_err(|e| io::Error::new(io::ErrorKind::NotFound, e.to_string()))?
        .join("sessions");
    if !legacy.is_dir() || paths_equivalent(primary, &legacy) {
        return Ok(0);
    }

    copy_missing_dir_entries(&legacy, primary)
}

fn copy_missing_dir_entries(src: &Path, dst: &Path) -> io::Result<usize> {
    fs::create_dir_all(dst)?;
    let mut copied = 0;
    for entry in fs::read_dir(src)? {
        let entry = entry?;
        let source = entry.path();
        let target = dst.join(entry.file_name());

        let file_type = entry.file_type()?;
        if file_type.is_dir() {

View on GitHub (pinned to 433685b202)