Hmbown/CodeWhale · error

this launcher does not support sandbox listing

Error message

this launcher does not support sandbox listing

What it means

list_job_sandboxes backs the reconciler's startup sweep and cancel path, discovering Codewhale-dispatch sandboxes by their job labels. The trait default stubs it with this bail so partial fixtures keep compiling. It fires when a launcher that never implemented listing is asked to enumerate sandboxes.

Solutions

  1. Implement fn list_job_sandboxes in your launcher to query the provider for dispatch-labeled sandboxes.
  2. Skip reconciliation gracefully (or use an empty listing) when the launcher intentionally does not support discovery.
  3. Point the reconciler at LiveDaytonaLauncher in production, which implements listing.

Example fix

null
Defensive patterns

Strategy: fallback

Validate before calling

let listings = launcher.list_job_sandboxes().unwrap_or_default();

Try / catch

let sandboxes = match launcher.list_job_sandboxes() {
    Ok(v) => v,
    Err(e) if e.to_string().contains("does not support sandbox listing") => Vec::new(),
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: The reconciler runs a startup sweep or cancel-time sweep and calls launcher.list_job_sandboxes() on a launcher whose impl relies on the default trait body (typically a test recorder).

Common situations: Starting the TUI/cloud-dispatch runner against a fake or custom launcher lacking reconciliation support; integrating a new provider before implementing discovery.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

    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>,
}

/// Provider receipt for a created sandbox. `toolbox_url` is the validated
/// per-sandbox toolbox origin returned by the create call, when present.
/// `pr_url` is intentionally omitted from this slice.
///
/// This is the infrastructure id of a created sandbox. It is not Computer
/// entitlement and must not be treated as provider-accepted active seconds.
#[derive(Debug, Clone, PartialEq, Eq)]

View on GitHub (pinned to 73e0f67d83)