Hmbown/CodeWhale · error · anyhow::Error

the ` ` profile carries identity only after ` install-bundle

Error message

the `{}` profile carries identity only after `{CLI_COMMAND} install-bundle`

What it means

The dedicated bundle profile is special: it carries the Codewhale identity inside the installed bundle itself. launch_spec rejects requesting that profile when no bundle is actually installed — without `install-bundle` the profile exists but has no identity to launch with.

Solutions

  1. Run `codewhale dsh install-bundle` to install the bundle into the dedicated profile, then launch again.
  2. Or launch with `--profile web`/`--profile headless`, which receive identity through the overlay patch instead.
  3. Check `codewhale dsh status` to confirm whether the bundle is installed.

Example fix

// before
codewhale dsh launch --profile codewhale
Error: the `codewhale` profile carries identity only after `codewhale install-bundle`

// after
codewhale dsh install-bundle
codewhale dsh launch --profile codewhale
Defensive patterns

Strategy: validation

Validate before calling

let status = codewhale_dsh_status()?;
let bundle_installed = status.record.as_ref().and_then(|r| r.bundle.as_ref()).is_some();
if profile_override == Some(bundle::BUNDLE_PROFILE) && !bundle_installed {
    return Err("bundle profile requires install-bundle first");
}

Type guard

fn bundle_profile_ready(status: &DshStatusReport) -> bool {
    status.record.as_ref().map_or(false, |r| r.bundle.is_some())
}

Try / catch

match launch_spec(&report, Some(bundle::BUNDLE_PROFILE), &[], &ws) {
    Err(e) if e.to_string().contains("install-bundle") => {
        run_install_bundle()?;
        launch_spec(&report, Some(bundle::BUNDLE_PROFILE), &[], &ws)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Passing the bundle profile name (bundle::BUNDLE_PROFILE) as `--profile` to a dsh launch command while record.bundle is None, i.e. `codewhale dsh install-bundle` was never run (or remove-bundle was run).

Common situations: Scripting a launch with the bundle profile on a machine where the bundle step was skipped; running remove-bundle and then launching with a stale script that still names the bundle profile.

Related errors


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

Appendix: source

Thrown at crates/tui/src/integrations/dsh/mod.rs:721

    let binary = report
        .detection
        .binary
        .clone()
        .ok_or_else(|| anyhow::anyhow!("dsh binary path is unknown"))?;
    let bundle_installed = record.bundle.is_some();
    let profile = profile_override.unwrap_or(if bundle_installed {
        bundle::BUNDLE_PROFILE
    } else {
        record.profile.as_str()
    });
    if !matches!(profile, "web" | "headless") && profile != bundle::BUNDLE_PROFILE {
        anyhow::bail!(
            "DSH profile must be `web`, `headless`, or `{}` (bundle), got `{profile}`",
            bundle::BUNDLE_PROFILE
        );
    }
    if profile == bundle::BUNDLE_PROFILE && !bundle_installed {
        anyhow::bail!(
            "the `{}` profile carries identity only after `{CLI_COMMAND} install-bundle`",
            bundle::BUNDLE_PROFILE
        );
    }
    let mut args = vec!["--profile".to_string(), profile.to_string()];
    if profile != bundle::BUNDLE_PROFILE {
        // The dedicated bundle profile carries the identity itself; the
        // shipped profiles get it through the overlay.
        args.push("--patch".to_string());
        args.push(report.overlay_path.display().to_string());
    }
    args.extend(extra_args.iter().cloned());
    let provider_env_vars: Vec<String> =
        record.identity.source.api_key_env.iter().cloned().collect();
    let strip_env = launch_env_strip_list(
        crate::config::cli_api_key_source().as_deref(),
        &provider_env_vars,
    );

View on GitHub (pinned to 73e0f67d83)