Hmbown/CodeWhale · error

dsh is offline

Error message

dsh is offline: {reason}

What it means

ensure_launchable_dsh verifies that the external `dsh` CLI (DeepSeek Harness) is installed and healthy before Codewhale launches through it. When the dsh process probe reports DshIntegrationState::Offline with a reason (e.g. the binary exists but fails to respond or reports an error), this bail aborts the launch with the probe's reason embedded in the message. The library throws it to fail loud instead of spawning a harness that cannot work.

Solutions

  1. Run `dsh --version` (or the probe command) manually to see the underlying failure and fix the root cause
  2. Reinstall the harness: `npm i -g @deepseek-ai/dsh`
  3. Check that the Node runtime required by dsh is installed and compatible
  4. Verify the dsh binary on PATH is the official one, not a broken wrapper: `which dsh`

Example fix

// before
// blindly launching dsh and hitting the bail
run_dsh(...)?;
// after
// probe and remediate first
if let DshIntegrationState::Offline { reason } = state {
    eprintln!("fixing offline dsh: {reason}");
    reinstall_dsh();
}
run_dsh(...)?;
Defensive patterns

Strategy: try-catch

Validate before calling

let output = std::process::Command::new("dsh").arg("--version").output()?;
if !output.status.success() { eprintln!("dsh offline: {}", String::from_utf8_lossy(&output.stderr)); }

Type guard

fn is_launchable(state: &DshIntegrationState) -> bool {
    !matches!(state, DshIntegrationState::NotInstalled | DshIntegrationState::Offline { .. })
}

Try / catch

match run_dsh(...) {
    Err(e) if e.to_string().starts_with("dsh is offline") => reinstall_or_repair_dsh(),
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Calling run_dsh when a `dsh` binary is on PATH but the health probe classifies it as Offline — e.g. the CLI crashes on invocation, is not executable by the current user, or its self-report errors.

Common situations: A broken or partially installed npm global package; `dsh` present but failing due to a corrupt install or incompatible Node runtime; PATH resolving to a stub/wrapper script that errors.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/df84658440768f50. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/integrations/cli.rs:531

                "  (receipt history is kept at {}; $DSH_HOME is never touched)",
                paths.receipt.display()
            );
            confirm(yes, "Remove the DSH integration files?")?;
            let removed = dsh::remove(&paths)?;
            println!("removed {} file(s)", removed.len());
            Ok(())
        }
    }
}

fn ensure_launchable_dsh(report: &DshStatusReport) -> Result<()> {
    match &report.state {
        DshIntegrationState::NotInstalled => {
            anyhow::bail!(
                "dsh is not on PATH; install the official DeepSeek Harness first (npm i -g @deepseek-ai/dsh)"
            )
        }
        DshIntegrationState::Offline { reason } => anyhow::bail!("dsh is offline: {reason}"),
        DshIntegrationState::Incompatible { reason, .. } => {
            anyhow::bail!("installed dsh is incompatible with this integration: {reason}")
        }
        _ => Ok(()),
    }
}

View on GitHub (pinned to 73e0f67d83)