Hmbown/CodeWhale · error
exec turn failed
Error message
exec turn failed: {error} What it means
When a CLI exec turn fails with an error category that maps to a non-1 exit code, run_exec_agent prints the failure to stderr and exits the process directly with that code; for the category that maps to exit code 1 it instead returns this anyhow error from the function. Either way the message surfaces the underlying turn error to the caller of the exec entrypoint.
Solutions
- Read the `{error}` text in the message/preceding stderr output to identify the underlying turn failure and fix that cause.
- For provider/API errors, verify the configured route (provider, model, API key) is valid and reachable.
- Retry the exec command if the failure was transient; non-1 exit codes are returned as process exit codes for that purpose.
- Inspect summary.error_category to map the failure to its documented exit code and handling in your script.
Example fix
// before (scripting blindly)
codewhale exec "prompt"
// after
codewhale exec "prompt" || { echo "exec failed: $?"; retry_or_alert; } Defensive patterns
Strategy: try-catch
Try / catch
match codewhale_exec_status {
0 => {}, // success
code @ 2.. => { eprintln!("exec failed with categorized exit {code}; see stderr"); }
_ => { eprintln!("exec turn failed (exit 1): inspect the error text"); }
} Prevention
- Validate provider routes and API keys before headless runs.
- Retry transient failures with backoff keyed on the categorized exit code.
- Capture stderr, since non-1 categories print the error there before exiting.
When it happens
Trigger: A `codewhale exec` turn fails (provider error, tool failure, aborted turn) and `exec_failure_exit_code(summary.error_category)` yields 1 — the error is propagated as `bail!("exec turn failed: {error}")`.
Common situations: Transient upstream/API errors during scripted exec runs; a misconfigured provider route in headless/CI usage; the prompt triggered a tool that failed and the turn aborted with a generic error category.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- exec turn ended with status
- Command failed with exit code
- dsh exited with status
- must be placed before `exec`. Use: codewhale exec
- 127
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/d9b0470726d17a06.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/exec_agent.rs:1444
if json_output {
println!("{}", serde_json::to_string_pretty(&summary)?);
}
if let Some(error) = summary.error.as_ref()
&& !error.trim().is_empty()
{
// Distinguish retryable infrastructure failures (provider/transport,
// after all in-session retries are exhausted) from genuine task
// failures so supervisors and bench harnesses can tell them apart at
// the process level without parsing the stream. Genuine failures
// keep the historical `bail!` → exit 1 path.
let exit_code = exec_failure_exit_code(summary.error_category.as_deref());
if exit_code != 1 {
eprintln!("Error: exec turn failed: {error}");
let _ = io::stdout().flush();
std::process::exit(exit_code);
}
bail!("exec turn failed: {error}");
}
if matches!(
summary.status.as_deref(),
Some("failed" | "canceled" | "interrupted")
) {
let status = summary.status.as_deref().unwrap_or("unknown");
bail!("exec turn ended with status {status}");
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::{ExecAgentEvents, exec_automation_services, exec_disallowed_tools};
use crate::core::engine::mock_engine_handle;
use crate::core::engine::tool_catalog::REQUEST_USER_INPUT_NAME;View on GitHub (pinned to 73e0f67d83)