Hmbown/CodeWhale · error
overlay is stale; run `{CLI_COMMAND} update` before install-
Error message
overlay is stale; run `{CLI_COMMAND} update` before install-bundle What it means
`install-bundle` refuses to run while `report.state` is `StaleConfig`: the overlay exists on disk but no longer matches the current Codewhale route (the overlay's SHA-256 drifted from the receipt's because provider, model, base_url, or workspace changed). Installing a bundle on top of a stale overlay would pin the bundle to an identity the user has already moved away from, so the CLI forces `update` first to re-pin the identity.
Source
Thrown at crates/tui/src/integrations/cli.rs:393
DshIntegrationCommand::Enable => {
let paths = DshPaths::from_process()?;
let record = dsh::set_disabled(&paths, false)?;
println!("enabled: {}", record.overlay_path.display());
Ok(())
}
DshIntegrationCommand::InstallBundle { app, yes } => {
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()View on GitHub (pinned to 8880682c63)
Solutions
- Run `codewhale integrations dsh update` to regenerate the overlay for the current route, then retry install-bundle
- If you hand-edited the overlay, let `update` rewrite it — the file is marked generated
- Use `codewhale integrations dsh status` to read the staleness reason and confirm it clears after update
Defensive patterns
Strategy: validation
Validate before calling
let (_paths, report) = status_report(config, workspace, false)?;
if matches!(report.state, DshIntegrationState::StaleConfig { .. }) {
println!("overlay is stale; run `codewhale integrations dsh update` first");
return Ok(());
} Type guard
fn overlay_fresh(report: &DshStatusReport) -> bool {
!matches!(report.state, DshIntegrationState::StaleConfig { .. })
} Prevention
- Run `update` after every provider/model/workspace change — it is cheap and re-pins the overlay
- Never hand-edit codewhale.patch.yml; its SHA-256 is the drift detector
- Gate bundle and launch flows on the typed state enum, not on file existence
When it happens
Trigger: `install-bundle` after changing the provider or default model in Codewhale config since the last `connect`/`update`; after hand-editing `codewhale.patch.yml`; after pointing Codewhale at a different workspace directory. The same guard pattern exists in `launch_spec` (dsh/mod.rs:630-634) with a matching message.
Common situations: Switching default model and immediately trying install-bundle; editing the generated overlay manually (its header says do not edit); running Codewhale from a different workspace than the one the overlay was generated for.
Related errors
- DSH is not connected; run `{CLI_COMMAND} connect`
- DSH is not connected; run `{CLI_COMMAND} connect` first
- no bundle is installed
- continual harness has no entry `{id}`
- dsh exited with status {code}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/eda3584bfc8e3ddb.
Report an issue: GitHub.