nikivdev/code · error

OpenAI API error {}: {}

Error message

OpenAI API error {}: {}

What it means

Thrown inside the OpenAI retry loop when the API returns a 4xx client error, which is treated as non-retryable. The status code and response body are embedded in the bail message; 5xx errors instead go to `last_error` and are retried.

Source

Thrown at src/commit.rs:12947

            let delay = Duration::from_secs(2u64.pow(attempt));
            print!("Retrying in {}s... ", delay.as_secs());
            io::stdout().flush().ok();
            std::thread::sleep(delay);
        }

        match client
            .post("https://api.openai.com/v1/chat/completions")
            .header("Authorization", format!("Bearer {}", api_key))
            .json(&body)
            .send()
        {
            Ok(resp) => {
                if !resp.status().is_success() {
                    let status = resp.status();
                    let text = resp.text().unwrap_or_default();
                    // Don't retry client errors (4xx)
                    if status.is_client_error() {
                        bail!("OpenAI API error {}: {}", status, text);
                    }
                    last_error = Some(format!("OpenAI API error {}: {}", status, text));
                    continue;
                }

                let parsed: ChatResponse =
                    resp.json().context("failed to parse OpenAI response")?;

                let message = parsed
                    .choices
                    .first()
                    .and_then(|c| c.message.as_ref())
                    .map(|m| m.content.trim().to_string())
                    .unwrap_or_default();

                if message.is_empty() {
                    bail!("OpenAI returned empty commit message");
                }

View on GitHub (pinned to a747e741ae)

Solutions

  1. Verify the API key is valid and has quota (e.g. GET /v1/models with the key).
  2. Check the model name in configuration matches a current OpenAI model.
  3. Reduce the prompt/diff size if the error body mentions token/context limits.
  4. Read the response body embedded in the error — it contains OpenAI's specific error code.

Example fix

// before
bail!("OpenAI API error {}: {}", status, text);
// after
bail!("OpenAI API error {}: {} (check OPENAI_API_KEY and model name)", status, text);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check API key before calling OpenAI
if std::env::var("OPENAI_API_KEY").map(|k| k.is_empty()).unwrap_or(true) {
    return Err(anyhow!("OPENAI_API_KEY is not set"));
}

Try / catch

match result {
    Err(e) if e.to_string().contains("OpenAI API error 401") => {
        eprintln!("Invalid OpenAI key: run the key setup again");
        Err(e)
    }
    Err(e) if e.to_string().contains("OpenAI API error 4") => {
        eprintln!("Client error, not retrying: {e}");
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: OpenAI API returns 400/401/403/404/422: invalid API key, malformed request body, unsupported/retired model name, or request exceeding the model's context window.

Common situations: Expired or revoked OPENAI_API_KEY; model renamed/retired (old model id in config); request payload too large for the model's context window; organization blocked or billing disabled.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/46ba26e41b8f5049. Report an issue: GitHub.