Hmbown/CodeWhale · error

Cloud agent sandbox disappeared before it was ready.

Error message

Cloud agent sandbox disappeared before it was ready.

What it means

During the readiness poll the provider answered 404, meaning the sandbox no longer exists even though create had succeeded moments earlier. Waiting is pointless, so the library fails fast with this message.

Solutions

  1. Re-dispatch the job to create a new sandbox
  2. Verify the API key/workspace matches the one used at create time
  3. Check the Daytona dashboard and audit logs for who deleted the sandbox
  4. Look for concurrent jobs operating on the same sandbox id
Defensive patterns

Strategy: retry

Validate before calling

// ensure the same workspace/key is used for create and poll
assert_eq!(api_key_workspace(&create_key), api_key_workspace(&poll_key));

Try / catch

match wait_ready(&receipt) {
    Err(e) if e.to_string().contains("disappeared") => re_dispatch(job),
    Err(e) => bail!(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: A GET on sandbox/{id} returns 404 during the READY_POLL_ATTEMPTS loop — the sandbox was destroyed externally, failed provisioning and was reaped, or the id is scoped to another project/region than the API key.

Common situations: Provider auto-reaping failed sandboxes, concurrent teardown by another job/agent, API key pointing at a different Daytona workspace than the one that created the sandbox.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

                    let text = response.text().unwrap_or_default();
                    if let Ok(parsed) = serde_json::from_str::<serde_json::Value>(&text)
                        && let Some(state) = parsed.get("state").and_then(|v| v.as_str())
                    {
                        match state {
                            "started" | "ready" => return Ok(()),
                            "error" | "destroyed" | "archived" => {
                                bail!("Cloud agent sandbox entered state '{state}'.");
                            }
                            _ => {}
                        }
                    } else {
                        return Ok(());
                    }
                }
                Err(error) => return Err(error),
                Ok(response) => {
                    if response.status().as_u16() == 404 {
                        bail!("Cloud agent sandbox disappeared before it was ready.");
                    }
                }
            }
            std::thread::sleep(READY_POLL_INTERVAL);
        }
        bail!("Cloud agent sandbox was not ready in time.");
    }

    fn clone_repository(&self, receipt: &SandboxReceipt, repo_url: &str, path: &str) -> Result<()> {
        let repo_url = validate_git_remote_url(repo_url)?;
        let api_key = Self::api_key()?;
        let url = Self::toolbox_base(receipt)?.join("git/clone")?;
        let body = serde_json::json!({ "url": repo_url, "path": path });
        let response = Self::send_json(reqwest::Method::POST, &url, &api_key, body)?;
        let status = response.status();
        if !status.is_success() {
            bail!("Cloud agent repository clone failed (HTTP {status}).");
        }

View on GitHub (pinned to 73e0f67d83)