Hmbown/CodeWhale · error

DSH is already connected; use

Error message

DSH is already connected; use `{CLI_COMMAND} update` to rewrite the overlay

What it means

Thrown by `run_dsh` during a DSH connect attempt when a status report shows an existing, non-disabled DSH integration record. Connecting would overwrite the existing overlay, so the library requires the explicit `update` subcommand instead.

Solutions

  1. Use `dsh update` to rewrite the existing overlay instead of connect
  2. Run `dsh disable` first if you genuinely want to re-connect from scratch
  3. Inspect `dsh status` to confirm the existing record before choosing update

Example fix

// before
$ codewhale dsh connect
error: DSH is already connected...
// after
$ codewhale dsh update
Defensive patterns

Strategy: validation

Validate before calling

// check state before connect
let report = status_report(&config, &workspace, false)?;
let already_connected = report.record.as_ref().is_some_and(|r| !r.disabled);
if already_connected { /* run update instead of connect */ }

Try / catch

match result {
    Err(e) if e.to_string().contains("already connected") => /* switch to `dsh update` */,
    other => return other,
}

Prevention

When it happens

Trigger: Running `dsh connect` when `report.record` exists with `disabled == false` — i.e. the harness is already connected and the overlay is active.

Common situations: Re-running connect after a successful setup; running connect in a fresh checkout/machine state check where the overlay file still exists; scripted re-provisioning that assumed connect is idempotent.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

                print_plan(&plan, "connect");
                if !report.detection.installed() {
                    println!(
                        "  warning: dsh is not on PATH; the plan is valid but launch will fail"
                    );
                }
            }
            Ok(())
        }
        DshIntegrationCommand::Connect {
            profile,
            allow_full_access,
            skin,
            yes,
        } => {
            let (paths, report) = status_report(config, workspace, allow_full_access)?;
            ensure_launchable_dsh(&report)?;
            if report.record.as_ref().is_some_and(|r| !r.disabled) {
                anyhow::bail!(
                    "DSH is already connected; use `{CLI_COMMAND} update` to rewrite the overlay"
                );
            }
            let identity = dsh::codewhale_route_identity(config, workspace)
                .map_err(|e| anyhow::anyhow!("cannot resolve the current Codewhale route: {e}"))?;
            let plan = dsh::plan(
                &paths,
                &report.detection,
                &identity,
                &profile,
                allow_full_access,
                skin,
                true,
            )?;
            print_plan(&plan, "connect");
            confirm(yes, "Write these Codewhale-owned files and connect DSH?")?;
            let record =
                dsh::apply_plan(&paths, &report.detection, &plan, DshReceiptEvent::Connect)?;

View on GitHub (pinned to 73e0f67d83)