{"record":{"id":"df84658440768f50","repo":"Hmbown/CodeWhale","slug":"dsh-is-offline-reason","errorCode":null,"errorMessage":"dsh is offline: {reason}","messagePattern":"dsh is offline: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/cli.rs","lineNumber":531,"sourceCode":"                \"  (receipt history is kept at {}; $DSH_HOME is never touched)\",\n                paths.receipt.display()\n            );\n            confirm(yes, \"Remove the DSH integration files?\")?;\n            let removed = dsh::remove(&paths)?;\n            println!(\"removed {} file(s)\", removed.len());\n            Ok(())\n        }\n    }\n}\n\nfn ensure_launchable_dsh(report: &DshStatusReport) -> Result<()> {\n    match &report.state {\n        DshIntegrationState::NotInstalled => {\n            anyhow::bail!(\n                \"dsh is not on PATH; install the official DeepSeek Harness first (npm i -g @deepseek-ai/dsh)\"\n            )\n        }\n        DshIntegrationState::Offline { reason } => anyhow::bail!(\"dsh is offline: {reason}\"),\n        DshIntegrationState::Incompatible { reason, .. } => {\n            anyhow::bail!(\"installed dsh is incompatible with this integration: {reason}\")\n        }\n        _ => Ok(()),\n    }\n}\n","sourceCodeStart":513,"sourceCodeEnd":538,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/integrations/cli.rs#L513-L538","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `dsh --version` (or the probe command) manually to see the underlying failure and fix the root cause","Reinstall the harness: `npm i -g @deepseek-ai/dsh`","Check that the Node runtime required by dsh is installed and compatible","Verify the dsh binary on PATH is the official one, not a broken wrapper: `which dsh`"],"exampleFix":"// before\n// blindly launching dsh and hitting the bail\nrun_dsh(...)?;\n// after\n// probe and remediate first\nif let DshIntegrationState::Offline { reason } = state {\n    eprintln!(\"fixing offline dsh: {reason}\");\n    reinstall_dsh();\n}\nrun_dsh(...)?;","handlingStrategy":"try-catch","validationCode":"let output = std::process::Command::new(\"dsh\").arg(\"--version\").output()?;\nif !output.status.success() { eprintln!(\"dsh offline: {}\", String::from_utf8_lossy(&output.stderr)); }","typeGuard":"fn is_launchable(state: &DshIntegrationState) -> bool {\n    !matches!(state, DshIntegrationState::NotInstalled | DshIntegrationState::Offline { .. })\n}","tryCatchPattern":"match run_dsh(...) {\n    Err(e) if e.to_string().starts_with(\"dsh is offline\") => reinstall_or_repair_dsh(),\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Check `dsh --version` succeeds before any launch","Reinstall the npm global package after Node upgrades","Keep PATH pointing at the official dsh binary"],"tags":["cli","external-tool","launch"],"backgroundTag":"command-not-found","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}