Hmbown/CodeWhale · error
Cloud job is and cannot be run; confirm it first with…
Error message
Cloud job {id} is {} and cannot be run; confirm it first with `/dispatch confirm {id}`. What it means
run_confirmed_job only drives cloud jobs in Launching or Running status. Any other status (e.g. pending confirmation, done, cancelled, failed) cannot be run, and the error points at the `/dispatch confirm <id>` command as the required gate.
Solutions
- Run `/dispatch confirm <id>` first, then call run again
- Check the job status with the dispatch overview/list command before running
- Create a new job if the old one is terminal (done/cancelled/failed)
Example fix
// before run_confirmed_job(store, "job42", ...) // after // confirm first via the command surface: // /dispatch confirm job42 run_confirmed_job(store, "job42", ...)
Defensive patterns
Strategy: validation
Validate before calling
let job = store.load(id)?;
if !matches!(job.status, CloudJobStatus::Launching | CloudJobStatus::Running) {
confirm_job(id)?; // /dispatch confirm <id>
} Prevention
- Always confirm jobs before running them
- Check job status before re-running a job id
- Treat terminal-status jobs (done/cancelled/failed) as non-rerunnable; create a new job
When it happens
Trigger: Calling run_confirmed_job (directly or via spawn_confirmed_runner) with a job id whose stored CloudJobStatus is not Launching or Running — typically a job that was never confirmed, or one already completed/cancelled.
Common situations: Forgetting `/dispatch confirm <id>` after creating a job, retrying a job that already finished, or attempting to re-run a cancelled job.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Agent Mail can be canceled only while queued
- Agent not found
- Agent Mail can be marked read only after delivery
- Cannot queue a parent message for agent
- Cloud agent sandbox entered state
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/69082724b28ab005.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/dispatch_runner.rs:83
/// Run one confirmed job end to end.
///
/// Requires the job to be `launching` (or `running`, for a resumed runner):
/// a `proposed` job is refused — confirmation is the caller's explicit act,
/// never the runner's. Every phase persists its transition so `/dispatch
/// show` and `/jobs` stream real progress, and a `canceled` record at any
/// checkpoint stops the run and tears the sandbox down.
pub fn run_confirmed_job(
store: &CloudJobStore,
id: &str,
launcher: &dyn DaytonaLauncher,
forge: &dyn ForgePr,
) -> Result<CloudJob> {
let mut job = store.load(id)?;
if !matches!(
job.status,
CloudJobStatus::Launching | CloudJobStatus::Running
) {
bail!(
"Cloud job {id} is {} and cannot be run; confirm it first with `/dispatch confirm {id}`.",
status_word(job.status)
);
}
match drive(store, &mut job, launcher, forge) {
Ok(()) => store.load(id),
Err(error) => {
let message = sanitize_error(&error.to_string());
// Re-load before writing any failure: a job the user canceled
// stays canceled — a later run error must not overwrite the
// user's terminal word with `failed`. The error is appended to
// the note instead. And if a cancel lands inside the load→save
// span of the failure write, the disk record (already
// `canceled`, with the user's note) wins and is left alone.
let current = match store.load(id) {
Ok(mut record) if record.status == CloudJobStatus::Canceled => {
record.finished_unix =
Some(record.finished_unix.unwrap_or_else(unix_timestamp));View on GitHub (pinned to 73e0f67d83)