Hmbown/CodeWhale · error

dsh binary path is unknown

Error message

dsh binary path is unknown

What it means

To install a bundle, `run_dsh` must know where the dsh binary lives so it can locate the installed package. It throws this when `report.detection.binary` is `None`, i.e. detection ran but could not resolve the dsh executable path even though a connection record exists.

Solutions

  1. Re-run detection/connect so the binary path is re-resolved: `codewhale connect` or the update command.
  2. Check `which dsh` in the current shell and fix PATH or reinstall dsh.
  3. If dsh was moved, update the configured binary path via the integration config.
  4. Reconnect after reinstalling so the record and detection agree, then retry install-bundle.
Defensive patterns

Strategy: validation

Validate before calling

if report.detection.binary.is_none() {
    eprintln!("dsh binary not found; install dsh or fix PATH, then re-run connect");
    return Ok(());
}

Prevention

When it happens

Trigger: `DshIntegrationCommand::InstallBundle` where the status report has a `record` but `report.detection.binary` is `None` (dsh binary removed, renamed, PATH changed, or detection failed).

Common situations: dsh was uninstalled or upgraded outside the integration after connecting; PATH differs between the shell that connected and the one running the command; dsh installed via a package manager that moved the binary.

Related errors


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

Appendix: source

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

            let app = dsh::DshAppBundle::parse(&app)
                .ok_or_else(|| anyhow::anyhow!("--app must be `web` or `headless`, got `{app}`"))?;
            let (paths, report) = status_report(config, workspace, false)?;
            ensure_launchable_dsh(&report)?;
            let record = report.record.as_ref().ok_or_else(|| {
                anyhow::anyhow!("DSH is not connected; run `{CLI_COMMAND} connect` first")
            })?;
            if let dsh::BundleAvailability::NotAvailable { reason } = &report.bundle_availability {
                anyhow::bail!("DSH plugin path not available: {reason}");
            }
            if matches!(report.state, DshIntegrationState::StaleConfig { .. }) {
                anyhow::bail!("overlay is stale; run `{CLI_COMMAND} update` before install-bundle");
            }
            let app_source = dsh::bundle::app_bundle_source(
                report
                    .detection
                    .binary
                    .as_ref()
                    .ok_or_else(|| anyhow::anyhow!("dsh binary path is unknown"))?,
                app,
            )?;
            let profile_dir = report
                .detection
                .dsh_home
                .join("profiles")
                .join(dsh::bundle::BUNDLE_PROFILE);
            println!("{RELATIONSHIP_LABEL} — install-bundle plan (nothing written yet)");
            println!(
                "  will write (Codewhale-owned): {}/{{package.json,cordis.patch.yml,README.md,NOTICE.md}}",
                paths.bundle_dir.display()
            );
            println!(
                "  cordis.patch.yml = the current overlay rows (sha256 {})",
                record.overlay_sha256
            );
            println!(
                "  will run: dsh plugin --profile {} add {}",

View on GitHub (pinned to 73e0f67d83)