coleam00/Archon · error · ClaudeApiResultError

Claude API error (${sdkErrorCode}): ${resultText}

Error message

Claude API error (${sdkErrorCode}): ${resultText}

What it means

streamClaudeMessages throws ClaudeApiResultError when the Claude Agent SDK stream ends with a result message flagged as an API error. The message embeds the SDK's error code (sdkErrorCode from the result message, plus api_error_status and terminal_reason logged under 'claude.result_api_error') followed by the accumulated result text, so callers can classify retryability from the code.

Source

Thrown at packages/providers/src/claude/provider.ts:1203

        (syntheticError !== undefined || resultMsg.terminal_reason === 'api_error')
      ) {
        const code = syntheticError?.code ?? 'unknown';
        const text =
          syntheticError?.text ||
          resultMsg.result ||
          sdkErrors?.join('; ') ||
          'API error result with no error text';
        getLog().error(
          {
            sessionId: resultMsg.session_id,
            errorCode: code,
            terminalReason: resultMsg.terminal_reason,
            apiErrorStatus: resultMsg.api_error_status,
            text,
          },
          'claude.result_api_error'
        );
        throw new ClaudeApiResultError(code, text);
      }

      // Fail-safe (never observed in practice): a synthetic error message
      // followed by a non-error result. Yield the withheld text late rather
      // than silently swallowing content.
      if (syntheticError !== undefined && !resultMsg.is_error) {
        getLog().warn(
          { sessionId: resultMsg.session_id, errorCode: syntheticError.code },
          'claude.synthetic_error_not_confirmed'
        );
        yield { type: 'assistant', content: syntheticError.text };
      }

      // SDKResultSuccess declares `is_error: boolean` (not literal false). When a
      // model terminates via a configured stop sequence (stop_reason ===
      // 'stop_sequence') the SDK can set is_error: true while keeping
      // subtype: 'success' — its encoding of "non-default termination, not a
      // failure". Treat that pair as a clean success so downstream consumers

View on GitHub (pinned to 0773b97458)

Solutions

  1. Read the sdkErrorCode embedded in the message to classify: rate-limit/overloaded → retry with backoff; authentication → re-authenticate the Claude SDK (fresh `claude login` / valid API key).
  2. Check apiErrorStatus and terminalReason in the 'claude.result_api_error' log for retryability.
  3. For rate limits, reduce parallelism or add exponential backoff before retrying sendQuery.
  4. Verify the configured model is available to the account and the prompt/context size is within limits.
Defensive patterns

Strategy: retry

Validate before calling

// before invoking the provider
const key = process.env.ANTHROPIC_API_KEY;
if (!key) {
  throw new Error('ANTHROPIC_API_KEY missing; fix auth before querying Claude');
}

Type guard

class ClaudeApiResultError extends Error {
  constructor(public code: string, public resultText: string) {
    super(`Claude API error (${code}): ${resultText}`);
  }
}
function isClaudeApiResultError(e: unknown): e is ClaudeApiResultError {
  return e instanceof ClaudeApiResultError;
}

Try / catch

try {
  await provider.sendQuery(req);
} catch (err) {
  if (isClaudeApiResultError(err) && /rate|overload|429|529/i.test(err.code)) {
    await sleep(backoff); // exponential backoff + jitter, then retry
  } else if (isClaudeApiResultError(err) && /auth|401|403/i.test(err.code)) {
    throw new Error('Claude authentication failed — re-authenticate the SDK');
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: The Claude API returns an error result for the query: rate limiting (429), API overload (529/5xx), invalid API key or expired subscription auth, prompt flagged by safety filters, or request/context limits exceeded — surfaced by the SDK as an is_error result message rather than a thrown exception.

Common situations: Hitting rate limits during parallel agent fan-out; Anthropic API incident or outage; expired OAuth session for a Claude subscription; model id not accessible to the account; oversized context from a huge repo snapshot.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/129e89ede7c4bf9f. Report an issue: GitHub.