Hmbown/CodeWhale · error

this launcher does not support patch collection

Error message

this launcher does not support patch collection

What it means

Default SandboxLauncher trait implementation for collect_patch: a launcher that did not override the method reports that it cannot collect the agent's work product (patch) from the sandbox. The default-impl pattern keeps unsupported operations explicit and failing loudly.

Solutions

  1. Use a launcher whose collect_patch is implemented for your platform so the patch can actually be read out.
  2. Check launcher selection: a completed job with this error usually means the wrong backend ran it.
  3. If no patch exists (job never ran), check the job status first instead of calling collect_patch.
  4. Treat this as a terminal environment limitation — re-run the job on a capable launcher to obtain the patch.

Example fix

// before
let patch = launcher.collect_patch(&receipt)?;
// after
let launcher = real_launcher_for_platform();
let patch = launcher.collect_patch(&receipt)?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn launcher_supports_patch(l: &dyn SandboxLauncher) -> bool {
    l.capabilities().contains(Capability::CollectPatch)
}

Try / catch

match launcher.collect_patch(&receipt) {
    Err(e) if e.to_string().contains("does not support patch collection") => {
        eprintln!("no patch available: this launcher cannot collect work products; re-run on a capable launcher");
    }
    other => { /* ... */ }
}

Prevention

When it happens

Trigger: Calling collect_patch on a receipt from a launcher that never implemented patch collection — e.g. after a run in a stubbed environment, or a dispatch flow that finished the harness but selected a launcher without a real collect_patch.

Common situations: Retrieving results of a cloud job run with a fallback/no-op launcher; environments where the sandbox filesystem cannot be read out; wiring mistakes that routed the job to the stub backend.

Related errors


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

Appendix: source

Thrown at crates/tui/src/cloud_dispatch.rs:1190

/// the full protocol.
pub trait DaytonaLauncher {
    /// Create the sandbox and return its id plus the (validated) toolbox URL.
    fn create_sandbox(&self, job: &CloudJob) -> Result<SandboxReceipt>;
    /// Block until the sandbox accepts toolbox calls (bounded poll).
    fn wait_ready(&self, _receipt: &SandboxReceipt) -> Result<()> {
        Ok(())
    }
    /// Clone the target forge repository inside the sandbox.
    fn clone_repository(&self, _receipt: &SandboxReceipt, _url: &str, _path: &str) -> Result<()> {
        bail!("this launcher does not support repository clones")
    }
    /// Run one harness command inside the sandbox and return bounded stdout.
    fn run_harness(&self, _receipt: &SandboxReceipt, _command: &HarnessCommand) -> Result<String> {
        bail!("this launcher does not support harness execution")
    }
    /// Collect the agent's work product from the sandbox.
    fn collect_patch(&self, _receipt: &SandboxReceipt) -> Result<PatchReceipt> {
        bail!("this launcher does not support patch collection")
    }
    /// Tear the sandbox down. Called on cancel, failure, and completion.
    fn teardown(&self, _receipt: &SandboxReceipt) -> Result<()> {
        bail!("this launcher does not support teardown")
    }
    /// List Codewhale-dispatch sandboxes with their job labels. Used by the
    /// reconciler (startup sweep and cancel); not part of the run protocol.
    fn list_job_sandboxes(&self) -> Result<Vec<LabeledSandbox>> {
        bail!("this launcher does not support sandbox listing")
    }
}

/// One dispatch-labeled sandbox discovered by the reconciler.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LabeledSandbox {
    pub sandbox_id: String,
    /// Job id from the `codewhale.job` label, when the label is present.
    pub job_id: Option<String>,

View on GitHub (pinned to 73e0f67d83)