Hmbown/CodeWhale · error · anyhow::Error
DSH plugin path not available
Error message
DSH plugin path not available: {reason} What it means
install_bundle checks the precomputed BundleAvailability before doing any work. When the plugin path (the pnpm-managed location where the Codewhale bundle would be added via `dsh plugin --profile codewhale add`) is not usable — pnpm missing, wrong version, unwritable path — it aborts with this error carrying the availability `reason`.
Solutions
- Install or enable pnpm (e.g. `corepack enable pnpm` or `npm i -g pnpm`) and confirm `pnpm --version` meets the requirement stated in the error's reason.
- Fix the path/permission issue named in the `{reason}` and retry `codewhale dsh install-bundle`.
- Verify the dsh plugin directory exists and is writable by the current user.
Example fix
// before codewhale dsh install-bundle Error: DSH plugin path not available: pnpm not found on PATH // after corepack enable pnpm pnpm --version codewhale dsh install-bundle
Defensive patterns
Strategy: validation
Validate before calling
if !matches!(availability, BundleAvailability::Available { .. }) {
if let BundleAvailability::NotAvailable { reason } = availability {
eprintln!("fix plugin path first: {reason}");
}
return Err(...);
} Type guard
fn pnpm_available(a: &BundleAvailability) -> Option<&str> {
match a { BundleAvailability::Available { pnpm_version } => Some(pnpm_version), _ => None }
} Try / catch
match install_bundle(&paths, &detection, runner, &availability, app) {
Err(e) if e.to_string().starts_with("DSH plugin path not available") => {
install_pnpm()?;
// recompute availability and retry
}
other => other?,
} Prevention
- Install pnpm (corepack enable) as part of environment setup.
- Check `pnpm --version` in preflight scripts.
- Ensure the dsh plugin directory is writable by the runtime user.
When it happens
Trigger: Calling `codewhale dsh install-bundle` (or update paths that reuse install_bundle) while the earlier availability probe returned BundleAvailability::NotAvailable { reason } — e.g. pnpm is not installed or its version is below the required minimum.
Common situations: Node/pnpm toolchain not installed; pnpm installed only via corepack and not enabled; restricted CI container lacking pnpm; permissions on the dsh plugin directory.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- DSH is not connected; run
- the ` ` profile carries identity only after ` install-bundle
- bundle already installed; use
- overlay is stale; run
- --app must be `web` or `headless`, got
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/a4a8cf064763f64c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/integrations/dsh/mod.rs:779
let status = command
.status()
.with_context(|| format!("launch {}", spec.binary.display()))?;
Ok(status.code().unwrap_or(1))
}
/// Install the Codewhale bundle into the dedicated `codewhale` DSH profile via
/// the documented `dsh plugin --profile codewhale add <path>` (pnpm).
pub(crate) fn install_bundle(
paths: &DshPaths,
detection: &DshDetection,
runner: &dyn DshRunner,
availability: &BundleAvailability,
app: DshAppBundle,
) -> Result<DshBundleRecord> {
let pnpm_version = match availability {
BundleAvailability::Available { pnpm_version } => pnpm_version.clone(),
BundleAvailability::NotAvailable { reason } => {
anyhow::bail!("DSH plugin path not available: {reason}")
}
};
let mut doc = DshReceiptDocument::load(&paths.receipt)?;
let Some(mut record) = doc.current.take() else {
anyhow::bail!("DSH is not connected; run `{CLI_COMMAND} connect` first");
};
if record.bundle.is_some() {
anyhow::bail!("bundle already installed; use `{CLI_COMMAND} update` or `remove-bundle`");
}
let overlay_text = std::fs::read_to_string(&paths.overlay)
.with_context(|| format!("read {}", paths.overlay.display()))?;
if sha256_hex(overlay_text.as_bytes()) != record.overlay_sha256 {
anyhow::bail!("overlay is stale; run `{CLI_COMMAND} update` before install-bundle");
}
// install-bundle defaults the palette on; `update --skin false` is the
// off switch. `connect --skin` records the same decision for a later update.
let skin = true;
// The ocean scene follows the recorded decision (default on).View on GitHub (pinned to 73e0f67d83)