ruvnet/ruflo · error · LLMProviderError

OPENAI_${response.status}

OPENAI_${response.status}

Error message

${message}

What it means

OpenAIProvider's fallback mapping for any status other than 401/429/404: LLMProviderError with code OPENAI_<status>, retryable=true only when status >= 500. The message is OpenAI's error.error.message ('Unknown error' if the body was not JSON).

Source

Thrown at v3/@claude-flow/providers/src/openai-provider.ts:480

    }

    const message = errorData.error?.message || 'Unknown error';

    switch (response.status) {
      case 401:
        throw new AuthenticationError(message, 'openai', errorData);
      case 429:
        const retryAfter = response.headers.get('retry-after');
        throw new RateLimitError(
          message,
          'openai',
          retryAfter ? parseInt(retryAfter) : undefined,
          errorData
        );
      case 404:
        throw new ModelNotFoundError(this.config.model, 'openai', errorData);
      default:
        throw new LLMProviderError(
          message,
          `OPENAI_${response.status}`,
          'openai',
          response.status,
          response.status >= 500,
          errorData
        );
    }
  }
}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Read error.statusCode, message, and error.details - OpenAI's message names the offending field or overload state
  2. For 400 context-length: shorten the prompt or switch to a larger-context model; for other 400s remove the unsupported parameter
  3. For 5xx (retryable=true): retry with backoff or fail over to another provider via the ProviderManager
  4. If 5xx persists, check status.openai.com before retrying harder

Example fix

// before
const res = await provider.complete({ ...req, maxTokens: 8192 }); // OPENAI_400: context length

// after - trim input to fit the model's context window
const res = await provider.complete({ ...req, prompt: truncate(req.prompt, 120_000), maxTokens: 4096 });
Defensive patterns

Strategy: try-catch

Type guard

import { LLMProviderError, isLLMProviderError } from './types.js';
function isOpenAIApiError(e: unknown): e is LLMProviderError {
  return isLLMProviderError(e) && e.provider === 'openai' && e.code.startsWith('OPENAI_');
}

Try / catch

try {
  return await provider.complete(req);
} catch (e) {
  if (isOpenAIApiError(e)) {
    if (e.retryable) return retryWithBackoff(() => provider.complete(req)); // 5xx only
    throw new BadRequestError(`openai rejected request (${e.statusCode}): ${e.message}`, { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: complete() receiving 400 (invalid arguments, context-length exceeded, unsupported parameter for the model), 403, or 5xx such as 503 'engine overloaded' / 500 from OpenAI.

Common situations: Prompt + completion exceeding the model's context window (400 'maximum context length'); parameter not supported by the chosen model; transient 5xx during OpenAI incidents.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/e6a812e764960441. Report an issue: GitHub.