{"record":{"id":"9c56c6d77ac9e3af","repo":"Hmbown/CodeWhale","slug":"dsh-binary-is-unknown","errorCode":null,"errorMessage":"dsh binary is unknown","messagePattern":"dsh binary is unknown","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/dsh/bundle.rs","lineNumber":329,"sourceCode":"        args: args.iter().map(|s| (*s).to_string()).collect(),\n        success,\n        output_sha256: sha256_hex(output.as_bytes()),\n        output_excerpt: excerpt.chars().take(400).collect(),\n    })\n}\n\n/// Install the app bundle (linked from the installed launcher) and then the\n/// Codewhale bundle, in that order so Codewhale's rows patch last.\npub(crate) fn install_into_profile(\n    runner: &dyn DshRunner,\n    detection: &DshDetection,\n    app: DshAppBundle,\n    bundle_dir: &Path,\n) -> Result<(PathBuf, Vec<PluginCommandOutcome>)> {\n    let binary = detection\n        .binary\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"dsh binary is unknown\"))?;\n    let app_source = app_bundle_source(binary, app)?;\n    let mut outcomes = Vec::new();\n    let app_source_str = app_source.display().to_string();\n    let first = run_dsh_plugin(runner, binary, BUNDLE_PROFILE, &[\"add\", &app_source_str])?;\n    let first_ok = first.success;\n    let first_excerpt = first.output_excerpt.clone();\n    outcomes.push(first);\n    if !first_ok {\n        anyhow::bail!(\n            \"dsh plugin add {} failed: {}\",\n            app.package_name(),\n            first_excerpt\n        );\n    }\n    let bundle_str = bundle_dir.display().to_string();\n    let second = run_dsh_plugin(runner, binary, BUNDLE_PROFILE, &[\"add\", &bundle_str])?;\n    let second_ok = second.success;\n    let second_excerpt = second.output_excerpt.clone();","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/integrations/dsh/bundle.rs#L311-L347","documentation":"`install_into_profile` needs the dsh binary to run `dsh plugin --profile codewhale add <path>`; this guard fires when `detection.binary` is None — detection recorded no dsh executable. It mirrors the CLI-level guard (cli.rs:400) one layer down, protecting programmatic callers of the bundle installer from a detection report that never carried a binary.","triggerScenarios":"Calling `dsh::bundle::install_into_profile` (as install-bundle does after its own checks) with a `DshDetection` whose binary field is None — dsh missing from PATH in the invoking environment, or a detection report built in a different (stripped) environment such as sudo, cron, or a service context.","commonSituations":"Automation invoking Codewhale under a minimal environment where PATH lacks the npm global bin; uninstalling dsh between status detection and the install step; constructing DshDetection from cached/stale data.","solutions":["Ensure dsh is on PATH for the process running the install (`which dsh` must succeed)","Reinstall dsh if it was removed: `npm i -g @deepseek-ai/dsh`","Re-run detection fresh rather than reusing a stale report","Run `codewhale integrations dsh status` first and require the `dsh binary:` line to show a path"],"exampleFix":"// before\nlet (dir, outcomes) = dsh::bundle::install_into_profile(runner, &detection, app, &bundle_dir)?;\n\n// after — fail with intent before spawning anything\nlet binary = detection.binary.as_ref().ok_or_else(|| {\n    anyhow::anyhow!(\"dsh binary is unknown; re-run detection with dsh on PATH\")\n})?;\nlet (dir, outcomes) = dsh::bundle::install_into_profile(runner, &detection, app, &bundle_dir)?;","handlingStrategy":"validation","validationCode":"if detection.binary.is_none() {\n    eprintln!(\"re-run detection with dsh on PATH before installing bundles\");\n    return Ok(());\n}","typeGuard":"fn detection_has_binary(detection: &dsh::DshDetection) -> bool {\n    detection.binary.is_some()\n}","tryCatchPattern":null,"preventionTips":["Build the detection report in the same environment that will run the plugin commands","Run status immediately before install-bundle so the binary path is fresh","Never cache DshDetection across environment changes (sudo, cron, shell switches)"],"tags":["rust","dsh","path","detection","bundle"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}