xai-org/grok-build · error

{msg}

Error message

{msg}

What it means

Generic terminal-error path of run_single_turn: the session channel yielded Some(Err(err)), the message is emitted via emitter.on_error (with a 'max_tokens' stop-reason override when the sampling error maps to MaxTokens), and the message is re-raised as anyhow!("{msg}"). It surfaces any underlying turn failure verbatim.

Source

Thrown at crates/codegen/xai-grok-pager/src/headless.rs:1334

                ))
            } else {
                err.to_string()
            };
            if let Some(usage) = xai_grok_shell::sampling::error::prompt_usage_from_error(&err) {
                match serde_json::to_value(&usage) {
                    Ok(v) => emitter.usage = Some(v),
                    // Log rather than swallow: a serialize failure would drop the frozen spend fields.
                    Err(e) => tracing::warn!(
                        error = %e,
                        "headless: failed to serialize prompt-error usage; spend fields dropped"
                    ),
                }
            }
            let stop_reason_override =
                (xai_grok_shell::sampling::error::stop_reason_for_turn_error(&err) == "MaxTokens")
                    .then_some("max_tokens");
            emitter.on_error(&msg, stop_reason_override);
            Err(anyhow::anyhow!("{msg}"))
        }
        None => Ok(()),
    };

    // A hard stdout write error outranks the normal outcome: output is dead, so exit non-zero.
    if let Some(err) = emitter.take_output_error() {
        return Err(anyhow::Error::new(err).context("headless: stdout write failed"));
    }
    outcome
}

/// Background work tracked for exit: bash/monitor tasks and background subagents, keyed by id.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum BackgroundWork {
    Task(String),
    Subagent(String),
}

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Read {msg} and stop_reason_override to identify the root cause
  2. If 'max_tokens': reduce prompt size or raise the output token limit
  3. For auth/network errors, fix credentials and retry with backoff
  4. Enable verbose logging to capture the provider response behind msg

Example fix

// before: one blind attempt
run_single_turn(&mut session, &options).await?;
// after: retry transient failures
match run_single_turn(&mut session, &options).await {
    Err(e) if is_retryable(&e) => {
        tokio::time::sleep(Duration::from_secs(2)).await;
        run_single_turn(&mut session, &options).await?;
    }
    other => other?,
}
Defensive patterns

Strategy: retry

Validate before calling

fn is_retryable(msg: &str) -> bool {
    msg.contains("rate limit") || msg.contains("timeout")
        || msg.contains("503") || msg.contains("connection")
}

Type guard

fn is_max_tokens_error(err: &xai_grok_shell::sampling::error::Error) -> bool {
    xai_grok_shell::sampling::error::stop_reason_for_turn_error(err) == "MaxTokens"
}

Try / catch

match run_single_turn(&mut session, &options).await {
    Err(e) if is_retryable(&e.to_string()) => {
        tokio::time::sleep(backoff(attempt)).await;
        retry(attempt + 1);
    }
    Err(e) => { emitter_on_error(&e.to_string()); std::process::exit(1); }
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Any error terminating the turn that is not max-turns: API/network failure, sampling error like context-length/MaxTokens, provider auth rejection, tool infrastructure crash — whatever {msg} carries.

Common situations: Prompt exceeding the model context window (stop_reason max_tokens); expired/invalid API key; provider 5xx or rate limiting; transient network drop mid-turn.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/d9fc42f265002161. Report an issue: GitHub.