{"record":{"id":"4f2a548eb3b41625","repo":"Hmbown/CodeWhale","slug":"dsh-binary-path-is-unknown","errorCode":null,"errorMessage":"dsh binary path is unknown","messagePattern":"dsh binary path is unknown","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/cli.rs","lineNumber":400,"sourceCode":"            let app = dsh::DshAppBundle::parse(&app)\n                .ok_or_else(|| anyhow::anyhow!(\"--app must be `web` or `headless`, got `{app}`\"))?;\n            let (paths, report) = status_report(config, workspace, false)?;\n            ensure_launchable_dsh(&report)?;\n            let record = report.record.as_ref().ok_or_else(|| {\n                anyhow::anyhow!(\"DSH is not connected; run `{CLI_COMMAND} connect` first\")\n            })?;\n            if let dsh::BundleAvailability::NotAvailable { reason } = &report.bundle_availability {\n                anyhow::bail!(\"DSH plugin path not available: {reason}\");\n            }\n            if matches!(report.state, DshIntegrationState::StaleConfig { .. }) {\n                anyhow::bail!(\"overlay is stale; run `{CLI_COMMAND} update` before install-bundle\");\n            }\n            let app_source = dsh::bundle::app_bundle_source(\n                report\n                    .detection\n                    .binary\n                    .as_ref()\n                    .ok_or_else(|| anyhow::anyhow!(\"dsh binary path is unknown\"))?,\n                app,\n            )?;\n            let profile_dir = report\n                .detection\n                .dsh_home\n                .join(\"profiles\")\n                .join(dsh::bundle::BUNDLE_PROFILE);\n            println!(\"{RELATIONSHIP_LABEL} — install-bundle plan (nothing written yet)\");\n            println!(\n                \"  will write (Codewhale-owned): {}/{{package.json,cordis.patch.yml,README.md,NOTICE.md}}\",\n                paths.bundle_dir.display()\n            );\n            println!(\n                \"  cordis.patch.yml = the current overlay rows (sha256 {})\",\n                record.overlay_sha256\n            );\n            println!(\n                \"  will run: dsh plugin --profile {} add {}\",","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/integrations/cli.rs#L382-L418","documentation":"`install-bundle` needs the resolved dsh binary path to locate the shipped app bundle inside the installed launcher (`dsh::bundle::app_bundle_source(binary, app)`). This guard fires when `report.detection.binary` is None — detection found no `dsh` executable on PATH. It is mostly defensive: `ensure_launchable_dsh` normally bails earlier with `NotInstalled`, so reaching this line means PATH or the dsh install changed between the two probes (e.g. dsh was uninstalled concurrently, or PATH differs under sudo).","triggerScenarios":"`install-bundle` when dsh vanished from PATH mid-command, when the command runs under a different environment (sudo, service context) where dsh is not on PATH, or when a partially-broken dsh install makes detection record a state without a binary.","commonSituations":"Running the CLI through sudo or a launchd/systemd context with a stripped PATH; uninstalling or reinstalling dsh while the command runs; nvm/asdf shims not loaded in the invoking shell.","solutions":["Confirm `which dsh` resolves in the exact shell/environment you invoke Codewhale from","Reinstall dsh (`npm i -g @deepseek-ai/dsh`) if it was removed mid-flight","Avoid sudo for this command; dsh detection relies on the user's PATH","Re-run `codewhale integrations dsh status` — the `dsh binary:` line states plainly whether a binary was found"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let (_paths, report) = status_report(config, workspace, false)?;\nif report.detection.binary.is_none() {\n    eprintln!(\"dsh binary not found on PATH; reinstall with npm i -g @deepseek-ai/dsh\");\n    return Ok(());\n}","typeGuard":"fn dsh_binary_known(report: &DshStatusReport) -> bool {\n    report.detection.binary.is_some()\n}","tryCatchPattern":null,"preventionTips":["Invoke dsh subcommands from a login shell where npm global bins are on PATH","Avoid sudo/service contexts that strip PATH before running integration commands","Refresh detection (status) immediately before acting on it"],"tags":["rust","dsh","path","environment","detection"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}