Profiles·Public

openai

semver>=4.0.0 <7.0.0postconditions93functions36last verified2026-06-24coverage score82%

Postconditions: what we check

  • create · authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Verify API key is correct and not revoked. Use environment variables, never hardcode keys. Alert operations team - this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • create · rate-limit-error
    warning
    WhenRate limit exceeded - RPM, TPM, RPD, TPD, or IPM (429)
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff retry logic for retries beyond the SDK's 2 automatic retries. Check rate limit headers (x-ratelimit-remaining-requests, x-ratelimit-remaining-tokens). Different endpoints have different limits (IPM for images, RPM/TPM for text). SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[2]
  • create · server-error
    error
    WhenOpenAI server error (500, 502, 503)
    ThrowsAPIError with status >= 500
    Required handlingCaller SHOULD treat as transient failure and retry with exponential backoff. SDK automatically retries 2 times. If errors persist, check OpenAI status page.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • create · timeout-error
    error
    WhenRequest timeout (default 10 minutes)
    ThrowsAPIConnectionTimeoutError
    Required handlingCaller SHOULD retry with exponential backoff. SDK automatically retries.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • create · invalid-request-error
    error
    WhenInvalid parameters (e.g., model not found, invalid temperature, file too large)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate parameters before making API call. Check error.message for specific parameter that failed. DO NOT retry without fixing the parameter.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[1]
  • generate · authentication-error
    error
    WhenInvalid API key (401)
    ThrowsAuthenticationError
    Required handlingVerify API key, DO NOT retry. Alert operations.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • generate · rate-limit-error-images
    error
    WhenImage generation rate limit exceeded (429) - measured in IPM (images per minute)
    ThrowsRateLimitError
    Required handlingImplement exponential backoff. Image generation has different rate limits than text completion (IPM vs RPM/TPM).
    costmediumin proddegraded serviceusers seeservice unavailablevisibilityvisible
    Sources[2]
  • generate · content-policy-violation
    error
    WhenPrompt violates content policy
    ThrowsBadRequestError with content policy violation message
    Required handlingDO NOT retry with same prompt. Return user-friendly error about content policy.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[1]
  • generate · server-error
    error
    WhenServer error (500+)
    ThrowsAPIError
    Required handlingRetry with exponential backoff. SDK auto-retries 2 times.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • embeddings.create · embeddings-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Embedding pipelines often run in background batch jobs where auth failures are silently swallowed, stopping the entire ingestion pipeline without alerting. Alert operations team immediately — this is a configuration error.
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[4]
  • embeddings.create · embeddings-rate-limit-error
    warning
    WhenRate limit exceeded (429) — TPM or RPM limits on embeddings endpoint
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff beyond the SDK's 2 automatic retries. Large batch embedding jobs (e.g., indexing entire document stores) routinely hit TPM limits. Without explicit handling, batch jobs fail mid-run and leave the vector store in a partially-indexed state. SDK automatically retries 2 times with exponential backoff.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[4]
  • embeddings.create · embeddings-token-limit-error
    error
    WhenInput exceeds model token limit (400) — 8192 tokens for ada-002
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST truncate or chunk input text before calling. DO NOT retry without reducing input size. text-embedding-ada-002 limit: 8192 tokens. text-embedding-3-small/large: higher limits but still finite. Silent swallowing means the document is never added to the index.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[4][5]
  • audio.transcriptions.create · transcription-invalid-file-error
    error
    WhenUnsupported audio format or file exceeds 25 MB size limit (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate file format and size before upload. Supported formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, webm. Maximum file size: 25 MB. DO NOT retry with the same file — fix the file first. Return user-friendly error indicating the file format or size issue.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[6][4]
  • audio.transcriptions.create · transcription-rate-limit-error
    warning
    WhenRate limit exceeded (429) — audio transcription has separate RPM limits
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff for batch transcription workflows. Whisper has stricter rate limits than text endpoints (measured in audio minutes/day). SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • audio.transcriptions.create · transcription-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • audio.speech.create · speech-input-too-long-error
    error
    WhenInput text exceeds 4096 character limit (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate input length before calling. Split text into chunks of ≤4096 characters and concatenate audio outputs. DO NOT retry with the same input without truncation.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[7][4]
  • audio.speech.create · speech-rate-limit-error
    warning
    WhenRate limit exceeded (429) — TTS has separate character-per-day limits
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff. TTS endpoints have character-per-minute and character-per-day quotas. SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seeservice unavailablevisibilityvisible
    Sources[4]
  • responses.create · responses-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • responses.create · responses-rate-limit-error
    warning
    WhenRate limit exceeded (429)
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff beyond SDK's 2 automatic retries. SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • responses.create · responses-incomplete-output
    error
    WhenResponse truncated due to max_output_tokens limit or content filter
    ThrowsDoes not throw — response.status === 'incomplete' with incomplete_details field
    Required handlingCaller MUST check response.status === 'incomplete' before consuming output. Check response.incomplete_details.reason: 'max_output_tokens' or 'content_filter'. For max_output_tokens: increase max_output_tokens or chunk the prompt. For content_filter: adjust the prompt or return user-friendly error. Treating incomplete responses as complete causes silent data loss.
    costmediumin prodsilent failureusers seelost transactionvisibilitysilent
    Sources[8]
  • responses.create · responses-image-error
    error
    WhenInvalid image input — unsupported format, too large, or content policy violation
    ThrowsBadRequestError with status 400 (or embedded in response.error)
    Required handlingCaller MUST validate image format, size, and content before sending. Check error code: invalid_image, invalid_base64_image, image_too_large, image_too_small, image_content_policy_violation, unsupported_image_media_type. DO NOT retry with the same image without fixing the issue.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[8][4]
  • moderations.create · moderation-rate-limit-error
    warning
    WhenRate limit exceeded (429) — moderations endpoint has separate RPM limits
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff. Moderation endpoints have independent RPM limits from completion endpoints. Apps that pre-screen every user message before forwarding to a model can easily hit per-minute limits. SDK automatically retries 2 times.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • moderations.create · moderation-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. If moderation errors are silently swallowed, user content is forwarded to the model without safety checks — a compliance and liability risk.
    costhighin prodsilent failureusers seeservice unavailablevisibilitysilent
    Sources[4]
  • batches.create · batches-invalid-file-error
    error
    WhenInvalid batch file format, exceeds 50,000 requests, or exceeds 200 MB (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate file format (JSONL), request count (≤50,000), and file size (≤200 MB) before calling. DO NOT retry with the same file without fixing the validation issue. Split large jobs into multiple smaller batch files.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[9][4]
  • batches.create · batches-async-failure
    error
    WhenBatch job fails or expires after submission (status: 'failed' or 'expired')
    ThrowsDoes not throw — batch.status becomes 'failed' or 'expired'; check batch.errors
    Required handlingCaller MUST poll batch status via batches.retrieve() until terminal state. Terminal states: 'completed', 'failed', 'expired', 'cancelled'. On 'failed': inspect batch.errors[] for per-request error codes and messages. On 'expired': resubmit the job (24h window passed without completion). Treating a 'failed' or 'expired' batch as completed causes silent data loss.
    costhighin prodsilent failureusers seelost transactionvisibilitysilent
    Sources[9]
  • fine_tuning.jobs.create · fine-tuning-invalid-file-error
    error
    WhenTraining file validation failed — invalid JSONL, wrong format, or file not ready (400)
    ThrowsBadRequestError with status 400; or FineTuningJob.error.code with param='training_file'
    Required handlingCaller MUST validate training file format before submitting. Training files must be JSONL with prompt/completion or messages format. File must be uploaded with purpose='fine-tune' via files.create(). File status must be 'processed' before referencing it in fine-tuning. Check FineTuningJob.error.code and FineTuningJob.error.message for details. DO NOT retry with the same file without fixing the format.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[10][4]
  • fine_tuning.jobs.create · fine-tuning-async-job-failure
    error
    WhenFine-tuning job fails during training (status: 'failed')
    ThrowsDoes not throw — FineTuningJob.status becomes 'failed'; inspect FineTuningJob.error
    Required handlingCaller MUST poll job status via fineTuning.jobs.retrieve() until terminal state. Terminal states: 'succeeded', 'failed', 'cancelled'. On 'failed': inspect FineTuningJob.error.code and FineTuningJob.error.message. Common failure causes: insufficient training data, data format errors, quota exceeded, model availability. Training compute costs are incurred even for failed jobs.
    costhighin prodsilent failureusers seelost transactionvisibilitysilent
    Sources[10]
  • files.create · files-invalid-format-or-size-error
    error
    WhenFile exceeds 512 MB, uses invalid format for purpose (e.g., non-JSONL for fine-tune/batch), or has malformed content (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate file format and size before uploading. Fine-tuning files: JSONL with prompt/completion or messages format required. Batch files: JSONL up to 200 MB, with specific per-request structure. Max individual file size: 512 MB. DO NOT retry with the same file without fixing the format or size. After upload, poll file.status until 'processed' before referencing the file ID.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[11][4]
  • files.create · files-processing-timeout-error
    error
    WhenFile processing exceeds the maximum wait time (default 30 minutes) when using waitForProcessing() before fine-tuning or batch submission
    ThrowsAPIConnectionTimeoutError from files.waitForProcessing()
    Required handlingCaller MUST handle timeout when polling file status via waitForProcessing(). Timeout does not mean the file failed — check file.status manually. Implement retry logic with a longer timeout or manual polling loop. Submitting a file ID before status='processed' causes downstream failures (fine-tuning and batch jobs reject unprocessed files).
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[11][4]
  • files.create · files-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • chat.completions.parse · parse-length-finish-reason-error
    error
    WhenResponse truncated due to max_tokens limit (finish_reason === 'length')
    ThrowsLengthFinishReasonError (extends OpenAIError)
    Required handlingCaller MUST catch LengthFinishReasonError when using chat.completions.parse(). This is thrown for EVERY choice with finish_reason 'length' — not just the last. Unlike completions.create() which silently returns truncated output, parse() makes truncation a hard error because JSON schema validation will fail anyway. Fix: increase max_tokens, reduce prompt size, or use a model with larger context. DO NOT retry with same parameters — the response will be truncated again.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[12][4]
  • chat.completions.parse · parse-content-filter-finish-reason-error
    error
    WhenResponse blocked by content filter (finish_reason === 'content_filter')
    ThrowsContentFilterFinishReasonError (extends OpenAIError)
    Required handlingCaller MUST catch ContentFilterFinishReasonError when using chat.completions.parse(). Thrown before any JSON parsing — the structured output is not available. Return a user-friendly error indicating the request was blocked by content policy. DO NOT retry with the same prompt without modifying content. Log occurrences for compliance and monitoring purposes.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[12][4]
  • chat.completions.parse · parse-rate-limit-error
    warning
    WhenRate limit exceeded (429)
    ThrowsRateLimitError with status 429
    Required handlingSame handling as chat.completions.create() — implement exponential backoff. SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • audio.translations.create · translation-invalid-file-error
    error
    WhenUnsupported audio format, file exceeds 25 MB, or corrupted file (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST validate file format and size before upload. Supported formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, webm. Maximum file size: 25 MB. DO NOT retry with the same file without fixing the issue. Return user-friendly error about file format or size constraint.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[13][4]
  • audio.translations.create · translation-rate-limit-error
    warning
    WhenRate limit exceeded (429) — audio translation shares rate limits with transcription
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff for batch translation workflows. Audio endpoints have separate rate limits measured in audio minutes/day. SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • vector_stores.create · vector-stores-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Vector store creation failures in background pipelines are silently swallowed, blocking all downstream file attachment operations. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[4]
  • vector_stores.create · vector-stores-rate-limit-error
    warning
    WhenRate limit exceeded (429) — vector store operations have separate rate limits
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff. SDK automatically retries 2 times with exponential backoff.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • vector_stores.files.create · vector-store-file-processing-failure
    error
    WhenFile processing fails after attachment (file.status becomes 'failed'); file.last_error.code is one of: 'server_error', 'unsupported_file', 'invalid_file'
    ThrowsDoes not throw — file.status becomes 'failed' and file.last_error is populated. Must be detected by checking file.status after polling or using createAndPoll().
    Required handlingCaller MUST use createAndPoll() or poll() to wait for processing completion, then check file.status === 'failed' and inspect file.last_error.code. 'unsupported_file': file type not supported — convert to supported format (PDF, DOCX, TXT, etc.). 'invalid_file': file content is corrupt or empty — re-upload the source file. 'server_error': transient failure — retry the attachment. Skipping the status check means the vector store appears to contain the file but search results return no content from it — a silent data loss.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[14][4]
  • vector_stores.files.create · vector-store-file-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • vector_stores.fileBatches.create · vector-store-file-batch-partial-failure
    error
    WhenOne or more files in the batch fail to process (batch.file_counts.failed_count > 0); batch.status may still be 'completed' even with failures
    ThrowsDoes not throw — batch.status is 'completed' but batch.file_counts.failed_count > 0. Per-file failure details available via listFiles() filtered to status='failed'.
    Required handlingCaller MUST use createAndPoll() to wait for processing, then check: 1. batch.status === 'failed' (entire batch failed) 2. batch.file_counts.failed_count > 0 (partial failure — some files missing from store) For failed files: call listFiles() filtered to status='failed', inspect each file's last_error to determine cause (unsupported_file, invalid_file, server_error). Partial failure means the vector store has incomplete content — search results will miss chunks from failed files without any user-visible error.
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[15][4]
  • uploads.create · uploads-expired-or-size-exceeded
    error
    WhenUpload expires after 1 hour without completion, or total size exceeds 8 GB (400/404)
    ThrowsNotFoundError (404) for expired upload; BadRequestError (400) for size exceeded
    Required handlingCaller MUST complete the multipart upload within 1 hour of calling uploads.create(). For large files: start parts.create() calls immediately after create(). If upload expires, call uploads.create() again and restart from the beginning — previously uploaded parts are lost. Track the uploadID and byte count; verify total matches declared bytes on complete(). Max upload size: 8 GB. Use uploads.complete() with md5 checksum for integrity.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[16][4]
  • uploads.create · uploads-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • uploads.complete · uploads-complete-byte-count-mismatch
    error
    WhenTotal bytes across all uploaded parts does not match the byte_count declared in uploads.create(), OR md5 checksum provided but does not match assembled content (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST track total bytes uploaded across all parts and verify they match the declared byte_count before calling complete(). If md5 is provided (recommended for integrity): compute MD5 of the full file before splitting and pass it in; mismatch means a part was corrupted in transit. DO NOT call complete() with mismatched bytes — the upload cannot be repaired, caller must restart from uploads.create() with fresh parameters. Log the part count, part IDs, and byte totals for debugging corrupted uploads.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[16][4]
  • uploads.complete · uploads-complete-expired-upload
    error
    WhenUpload was not completed within 1 hour of creation (expired), or upload was previously cancelled. NotFoundError thrown (404).
    ThrowsNotFoundError with status 404
    Required handlingCaller MUST call uploads.complete() within 1 hour of uploads.create(). For large files with many parts: start parts.create() calls immediately after create() and track time remaining in the 1-hour window. If expired: entire upload is lost — restart from uploads.create() with fresh bytes. Implement a deadline guard: if time elapsed > 50 minutes, cancel and restart rather than risk partial completion failure. Track upload creation timestamp alongside uploadID.
    costhighin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[16][4]
  • uploads.complete · uploads-complete-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Alert operations team — this is a configuration error. The upload cannot be recovered without a valid API key.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • uploads.parts.create · uploads-parts-size-exceeded
    error
    WhenIndividual part exceeds 64 MB limit (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST split file into chunks of ≤64 MB before calling parts.create(). Recommended chunk size: 32–50 MB for reliable uploads with retry headroom. Track part size before upload; reject oversized chunks without calling API. Total upload may be up to 8 GB across all parts.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[17][4]
  • uploads.parts.create · uploads-parts-invalid-upload-state
    error
    WhenUpload is expired (>1h since creation), cancelled, or already completed. NotFoundError (404) thrown when attempting to add parts.
    ThrowsNotFoundError with status 404
    Required handlingCaller MUST verify uploadID is valid and upload is in 'pending' state before calling parts.create(). Store upload creation timestamp; abort parallel part uploads if the 1-hour deadline is approaching. When running parts in parallel: if any part returns NotFoundError, cancel all remaining in-flight part uploads immediately to avoid wasted API calls. On expiry: restart from uploads.create() — all previously uploaded parts are lost.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[17][4]
  • uploads.parts.create · uploads-parts-rate-limit-error
    warning
    WhenRate limit exceeded during parallel part uploads (429)
    ThrowsRateLimitError with status 429
    Required handlingCaller MUST implement concurrency limits when uploading parts in parallel. Recommended: limit to 3-5 concurrent part uploads with exponential backoff on 429. SDK retries automatically (2 retries with exponential backoff) but application-level concurrency control prevents cascading rate limit failures. Track failed part IDs; retry only failed parts (completed parts need not be re-uploaded).
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • responses.parse · responses-parse-non-strict-tool-error
    error
    WhenAny tool in the request is not of type 'function', or a function tool does not have strict: true set. OpenAIError thrown client-side before any API call is made.
    ThrowsOpenAIError (not an HTTP error class) with message about strict: true requirement
    Required handlingCaller MUST set strict: true on all function tools passed to responses.parse(). Prefer zodResponseFormat() or explicitly constructed json_schema with strict: true. Use responses.create() instead if tools do not support strict mode. This error is configuration-only — fix the tool definition, not the runtime logic.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[18][4]
  • responses.parse · responses-parse-malformed-json-output
    error
    WhenModel returns output that does not conform to the requested json_schema format. JSON.parse() throws SyntaxError inside parseTextFormat() — not caught by the SDK. Can occur when model generates partial JSON (e.g. context-length truncation), or when response.status is 'incomplete' due to max_output_tokens limit.
    ThrowsSyntaxError: Unexpected token ... (from JSON.parse inside ResponsesParser)
    Required handlingCaller MUST wrap responses.parse() in try-catch that handles both APIError and SyntaxError separately. Check response.status before trusting output_parsed — if status is 'incomplete', the model ran out of tokens and the JSON may be truncated. Use response.incomplete_details to understand why generation stopped. Consider increasing max_output_tokens or chunking the prompt for long outputs. DO NOT assume output_parsed is populated when status !== 'completed'.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[18][12]
  • responses.parse · responses-parse-rate-limit-error
    warning
    WhenRate limit exceeded (429) — same limits as responses.create()
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff for batch structured-output workflows. SDK automatically retries 2 times with exponential backoff. Structured output workflows often run in tight loops (e.g. document extraction pipelines) where rate limiting is more likely than in interactive chat flows.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • realtime.sessions.create · realtime-sessions-authentication-error
    error
    WhenInvalid or missing API key (401)
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT pass the ephemeral token to the client if token generation fails. The client-side WebRTC connection will fail silently if given an invalid token. Server MUST handle AuthenticationError and return 500 to the client rather than passing through a null/undefined token. Alert operations team — this is a configuration error.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • realtime.sessions.create · realtime-sessions-permission-denied
    error
    WhenAccount does not have Realtime API access enabled, or the requested model is not available on the account's tier. PermissionDeniedError (403).
    ThrowsPermissionDeniedError with status 403
    Required handlingCaller MUST check for PermissionDeniedError separately from AuthenticationError. This is NOT a transient error — retrying will not help. Return a clear error to the client: "Voice features are not available on this plan." Check OpenAI account dashboard to enable Realtime API access. Log error.code from the response for support escalation.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • realtime.sessions.create · realtime-sessions-token-expiry-silent-failure
    warning
    WhenEphemeral client secret expires (default 10 minutes) before the client uses it to establish a WebRTC session. No error is thrown at token creation — the failure is silent and deferred to WebRTC connection establishment on the client side.
    ThrowsNo exception at token creation; WebRTC connection fails silently on client
    Required handlingCaller MUST generate ephemeral tokens as close to client usage as possible. DO NOT pre-generate tokens and cache them for reuse across multiple client sessions. If token TTL must be extended: set expires_after.seconds to match expected client wait time (max 7200 seconds / 2 hours). Front-end clients MUST implement reconnection logic that requests a new token from the server when the WebRTC connection fails — token expiry looks identical to a network error from the client's perspective. Server MUST log the token's expires_at timestamp alongside the session to diagnose client-side reconnection failures.
    costmediumin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[19][4]
  • responses.compact · responses-compact-not-found-error
    error
    Whenprevious_response_id references a non-existent or expired response (404)
    ThrowsNotFoundError with status 404
    Required handlingCaller MUST catch NotFoundError and handle the missing conversation gracefully. DO NOT silently discard the error — the compaction did not occur. Options: (1) restart the conversation from scratch, (2) fall back to passing full conversation history in the next responses.create() call. Log the failed previous_response_id for debugging. Agent and chatbot flows that rely on compaction to stay within context limits will silently lose the entire conversation history if this error is not caught.
    costmediumin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[8][4]
  • responses.compact · responses-compact-rate-limit-error
    warning
    WhenRate limit exceeded during compaction model call (429)
    ThrowsRateLimitError with status 429
    Required handlingCaller MUST catch RateLimitError and implement exponential backoff. Compaction consumes tokens (model generates the summary), so it counts against the same rate limits as responses.create(). High-frequency agent loops that compact every few turns may hit rate limits unexpectedly. If compaction fails: fall back to including the full history or reduce compaction frequency.
    costlowin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • responses.compact · responses-compact-bad-request-error
    error
    WhenInvalid model ID or unsupported model for compaction (400)
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST specify a valid model in ResponseCompactParams.model. Use the same model that generated the original conversation to ensure consistent token counting. BadRequestError is not retryable — fix the model ID before retrying.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • vector_stores.search · vector-stores-search-not-found-error
    error
    WhenvectorStoreID references a deleted or non-existent vector store (404)
    ThrowsNotFoundError with status 404
    Required handlingCaller MUST catch NotFoundError and handle gracefully in the RAG pipeline. A missing vector store means search will return no results AND an exception — do not assume empty results on error. Options: (1) re-create the vector store and re-index documents, (2) return a graceful "knowledge base unavailable" response to the user. Log the invalid vectorStoreID to detect environment/config drift (dev vs prod stores). Production RAG apps often have different vector store IDs per environment — a misconfigured env var causes this to fail on every query.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[20][4]
  • webhooks.unwrap · webhooks-invalid-signature-error
    error
    WhenThe webhook signature header does not match the expected HMAC-SHA256 value, or the timestamp in webhook-timestamp header is older than the tolerance (default 300 seconds = 5 minutes), or the timestamp is too far in the future (replay attack prevention), or the timestamp format is not a valid integer.
    ThrowsInvalidWebhookSignatureError (extends Error, NOT APIError)
    Required handlingCaller MUST catch InvalidWebhookSignatureError to prevent webhook processing from crashing. Return HTTP 400 to OpenAI on signature failure — do NOT return 200 as that tells OpenAI the event was successfully processed. IMPORTANT: InvalidWebhookSignatureError extends plain Error, NOT APIError. Catch blocks that only catch OpenAIError or APIError will miss this error. Pattern: catch (err) { if (err instanceof OpenAI.InvalidWebhookSignatureError) return res.status(400).send('Invalid signature'); } Stale webhooks (older than tolerance) are rejected — increase tolerance param if clock skew between your servers and OpenAI is causing false rejections.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[21][4]
  • webhooks.unwrap · webhooks-missing-secret-error
    error
    WhenThe webhook secret is not configured — either OPENAI_WEBHOOK_SECRET env var is not set, webhookSecret was not passed to OpenAI() constructor, and no secret was passed to the unwrap() call directly. Or required headers (webhook-signature, webhook-timestamp, webhook-id) are absent from the request.
    ThrowsError (plain, not InvalidWebhookSignatureError or APIError)
    Required handlingCaller MUST catch plain Error in addition to InvalidWebhookSignatureError. Missing secret is a configuration error that causes ALL webhook verifications to fail — surface to operations team immediately. Required headers (webhook-signature, webhook-timestamp, webhook-id) must be forwarded from the raw HTTP request to unwrap(). If using Next.js, use req.headers directly — do NOT rely on framework-normalized header objects that may lowercase or drop non-standard headers. Return HTTP 400 on missing secret/header errors.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[21]
  • webhooks.unwrap · webhooks-json-parse-error
    warning
    WhenThe webhook payload is valid UTF-8 and passes signature verification but is not valid JSON (e.g. truncated payload, encoding corruption in transit, middleware that modified the body after signature was computed).
    ThrowsSyntaxError from JSON.parse()
    Required handlingCaller MUST include plain Error handling to catch SyntaxError from JSON.parse. This is rare in practice but can occur if the request body was processed by middleware (bodyParser, express.json()) before reaching the webhook handler. Raw body MUST be used for signature verification — never parse the body first. In Express: use express.raw({ type: 'application/json' }) for the webhook route. In Next.js: read from req.body as string or use the raw body from the request stream.
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[21]
  • webhooks.verifySignature · webhooks-verify-invalid-signature-error
    error
    WhenThe HMAC-SHA256 signature in the webhook-signature header does not match the expected value computed from the payload, webhook-id, and webhook-timestamp. Also thrown when: timestamp is more than tolerance seconds in the past (default 5 min), timestamp is more than tolerance seconds in the future, or timestamp is not a valid integer.
    ThrowsInvalidWebhookSignatureError (extends Error, NOT APIError)
    Required handlingCaller MUST catch InvalidWebhookSignatureError and return HTTP 400 to OpenAI. Do NOT swallow this error and process the event — that defeats the security purpose. Note: If clock skew causes legitimate events to fail, adjust the tolerance parameter: await openai.webhooks.verifySignature(payload, headers, secret, 600); // 10 minute window IMPORTANT: InvalidWebhookSignatureError extends plain Error, not APIError. Pattern: catch (err) { if (err instanceof OpenAI.InvalidWebhookSignatureError) return res.status(400).send(); }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[21][4]
  • webhooks.verifySignature · webhooks-verify-missing-secret-error
    error
    WhenThe webhook secret is undefined, null, or empty string — not set via OPENAI_WEBHOOK_SECRET env var, not passed to OpenAI() constructor, and not passed directly to verifySignature(). Or required webhook headers are missing from the request (webhook-signature, webhook-timestamp, webhook-id).
    ThrowsError (plain, not InvalidWebhookSignatureError or APIError)
    Required handlingMissing webhook secret causes every verification call to throw — this is a configuration error, not a per-request error. Alert operations team. OPENAI_WEBHOOK_SECRET must be set in production environment — add it to deployment secrets and verify its presence on application startup. Missing headers: ensure the raw HTTP headers are passed unmodified. Some middleware strips non-standard headers or lowercases them — the SDK normalizes header names so case is not an issue, but headers must be present.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[21]
  • webhooks.verifySignature · vector-stores-search-rate-limit-error
    warning
    WhenSearch rate limit exceeded (429) — common in high-frequency RAG loops
    ThrowsRateLimitError with status 429
    Required handlingCaller MUST catch RateLimitError and implement exponential backoff. RAG pipelines that search on every user message are especially vulnerable to sustained rate limiting during traffic spikes. Consider caching frequent queries and implementing request queuing. Rate limit errors from vector store search are distinct from chat completion rate limits — they may have different limits and windows.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • responses.inputTokens.count · responses-input-tokens-context-overflow-error
    error
    WhenInput exceeds the model's context window with truncation set to 'disabled' (the default). The count call fails with BadRequestError (400) rather than returning the token count.
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST catch BadRequestError when using this as a pre-flight check. The count failing means the subsequent responses.create() would also fail with the same error — take corrective action before attempting the real call. Options: (1) truncate or summarize input, (2) use truncation: 'auto' in the count call to get the count after truncation, (3) compact the conversation using responses.compact() first. Do NOT treat BadRequestError from count() as a transient error — it indicates the input is too large for the model, not a service issue.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[22][4]
  • responses.inputTokens.count · responses-input-tokens-authentication-error
    error
    WhenInvalid or missing API key (401) — token counting requires authentication
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST catch AuthenticationError when using token count as a pre-flight check. A missing API key means ALL subsequent API calls will also fail. Surface to operations team immediately — this is a configuration error. Token count calls in background jobs (e.g., pre-processing pipelines) may fail silently if this error is swallowed.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • responses.stream · responses-stream-premature-termination-error
    error
    WhenThe stream terminates before producing a complete response. Causes: network interruption mid-stream, server closing the SSE connection early, or invalid event sequence (e.g., first event is not 'response.created'). This error only surfaces when .finalResponse() or .done() is awaited — the stream object itself does not throw at creation time.
    ThrowsOpenAIError('stream ended without producing a ChatCompletion')
    Required handlingCaller MUST await stream.finalResponse() inside a try-catch block. If only iterating over stream events via 'for await', the loop may complete without error even when the response is incomplete — always follow iteration with await stream.finalResponse(). Implement retry logic for transient network errors: create a new stream using response_id to resume from where the stream ended. Pattern: try { const response = await stream.finalResponse(); } catch (err) { if (err instanceof OpenAI.OpenAIError) { /* handle */ } }
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[23][24]
  • responses.stream · responses-stream-abort-error
    warning
    WhenThe stream is aborted by calling stream.abort() — either explicitly by the caller (e.g., request timeout, user cancellation) or via the AbortController passed to the options parameter. Aborted streams do not produce a final response.
    ThrowsAPIUserAbortError
    Required handlingCaller MUST handle APIUserAbortError distinctly from other OpenAIError subtypes. After aborting, do NOT call finalResponse() as it will throw. Common pattern in server-side code: wrap stream in a timeout that calls stream.abort() — ensure the abort is caught and surfaced as a user-facing error. APIUserAbortError does NOT extend APIError — it extends OpenAIError. Pattern: stream.on('abort', (err) => { /* handle abort */ }); // or in try-catch around finalResponse(): } catch (err) { if (err instanceof OpenAI.APIUserAbortError) { /* user cancelled */ } }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[24][4]
  • responses.stream · responses-stream-authentication-error
    error
    WhenThe API key is invalid, missing, or revoked (HTTP 401). The error occurs during the initial HTTP request that opens the SSE stream — before any events are emitted. Surfaces via the EventStream 'error' event and rejects stream.done() / stream.finalResponse().
    ThrowsAuthenticationError with status 401 (wrapped in OpenAIError by EventStream)
    Required handlingCaller MUST catch AuthenticationError when awaiting stream.finalResponse(). Auth errors from streaming calls fail immediately, not after partial data. This is a configuration error — alert operations, do NOT retry with same key.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • conversations.items.create · conversations-items-not-found-error
    error
    WhenThe conversationID does not correspond to an existing conversation — either it was never created, has been deleted, or belongs to a different project/org. Also thrown if the conversation has expired (managed conversations have TTLs).
    ThrowsNotFoundError with status 404
    Required handlingCaller MUST catch NotFoundError to detect stale or invalid conversation IDs. In agent frameworks that cache conversation IDs across requests, the conversation may be deleted server-side (TTL expiry, explicit delete, or cleanup job). On 404: create a new conversation via openai.conversations.create() and rebuild conversation history from local state before continuing. Do NOT silently swallow — the agent's conversation context is lost.
    costhighin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[25][4]
  • conversations.items.create · conversations-items-rate-limit-error
    warning
    WhenThe rate limit for conversation item creation is exceeded (HTTP 429). Agent frameworks that call conversations.items.create() on every turn — to persist tool results and model outputs — generate high request volumes that can exceed per-minute limits during traffic spikes.
    ThrowsRateLimitError with status 429
    Required handlingCaller SHOULD implement exponential backoff for RateLimitError. SDK auto-retries 2 times with backoff, but high-frequency agent loops may exhaust retries. Consider batching multiple items into a single call (up to 20 items per request) to reduce API calls per agent turn. Rate limit here is distinct from the model inference rate limits.
    costmediumin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[4]
  • conversations.items.create · conversations-items-invalid-request-error
    error
    WhenThe request body contains invalid item data — more than 20 items in a single request, items with invalid types, or items that reference non-existent tool call IDs (e.g., a tool result item referencing a call_id not in history).
    ThrowsBadRequestError with status 400
    Required handlingCaller MUST NOT retry without fixing the request structure. Split batches exceeding 20 items into multiple calls. Ensure tool result items reference valid call_ids from the model's prior output. Do NOT retry bad request errors — they are structural, not transient.
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[4]
  • chat.completions.stream · stream-length-finish-reason-error
    error
    WhenResponse truncated due to max_tokens limit (finish_reason === 'length'). Thrown during chunk accumulation inside the stream — surfaces when awaiting stream.finalChatCompletion() or stream.done(). chat.completions.create({stream:true}) would silently return truncated output; this helper converts it to an exception.
    ThrowsLengthFinishReasonError (extends OpenAIError)
    Required handlingCaller MUST catch LengthFinishReasonError when awaiting stream.finalChatCompletion(). This distinguishes stream() from create({stream:true}) — stream() makes truncation a hard error so callers cannot silently consume incomplete output. Fix: increase max_tokens, reduce prompt size, or switch to a model with larger context. DO NOT retry with same parameters — response will be truncated again. Pattern: try { const completion = await stream.finalChatCompletion(); } catch (err) { if (err instanceof OpenAI.LengthFinishReasonError) { /* truncation */ } }
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[26][4]
  • chat.completions.stream · stream-content-filter-finish-reason-error
    error
    WhenResponse blocked by content filter (finish_reason === 'content_filter'). Thrown during chunk accumulation — surfaces when awaiting stream.finalChatCompletion() or stream.done().
    ThrowsContentFilterFinishReasonError (extends OpenAIError)
    Required handlingCaller MUST catch ContentFilterFinishReasonError when using stream(). Content filter errors are thrown DURING streaming — no partial output is available, unlike completions.create({stream:true}) which may stream partial content before cutting off. Return user-friendly error indicating content policy blocked the response. Log occurrences for compliance monitoring. DO NOT retry with the same prompt without modifying content.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[26][4]
  • chat.completions.stream · stream-abort-error
    warning
    WhenThe stream is aborted — either via stream.controller.abort() explicitly, via an AbortController signal passed in options, or via stream.abort() method. Surfaces as APIUserAbortError when awaiting finalChatCompletion().
    ThrowsAPIUserAbortError (extends OpenAIError, NOT APIError)
    Required handlingCaller MUST handle APIUserAbortError separately from other OpenAIError subtypes. APIUserAbortError extends OpenAIError, NOT APIError — catch blocks that only catch APIError will miss this. Common pattern: server-side request timeout that aborts the stream. After abort, do NOT call finalChatCompletion() expecting a result. Pattern: stream.controller.abort(); // or pass AbortController to options try { await stream.finalChatCompletion(); } catch (err) { if (err instanceof OpenAI.APIUserAbortError) { /* user cancelled */ } }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[26][4]
  • chat.completions.stream · stream-premature-termination-error
    error
    WhenThe stream terminates before producing a complete chat completion. Causes: network interruption mid-stream, server closing SSE connection early, or invalid event sequence from the API. Surfaces when awaiting stream.finalChatCompletion() — the for-await loop completes without error but no completion was produced.
    ThrowsOpenAIError('stream ended without producing a ChatCompletion')
    Required handlingCaller MUST await stream.finalChatCompletion() in a try-catch. If only iterating events via 'for await', the loop ends without error even when the completion is missing — always check with finalChatCompletion(). Retry with a fresh stream() call for transient network errors. Pattern: try { const completion = await stream.finalChatCompletion(); } catch (err) { if (err instanceof OpenAI.OpenAIError) { /* stream failed */ } }
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[27][4]
  • chat.completions.runTools · run-tools-n-gt-1-error
    error
    Whenparams.n is set to a value greater than 1. Thrown client-side before any API call — the convenience runner only supports producing a single completion path.
    ThrowsOpenAIError('ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly.')
    Required handlingCaller MUST NOT set n>1 when using runTools() or stream(). Use chat.completions.create() directly if multiple completions (n>1) are needed. This error fires before any network request — it is a configuration error, not a transient failure. Remove or set n=1 in params.
    costlowin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[27][4]
  • chat.completions.runTools · run-tools-missing-function-error
    error
    WhenA tool in the tools array does not have an associated function implementation in the RunnableFunction map. The model calls a tool by name that was declared in the schema but whose executor function was not provided to runTools().
    ThrowsOpenAIError('Tool given to `.runTools()` that does not have an associated function')
    Required handlingCaller MUST ensure every tool definition passed to runTools() has a matching function implementation in the tools map. This is a programming error — the tool schema and the function implementations must stay in sync. When adding a new tool to the schema, always add its executor. This throws mid-run (when the model first calls the missing tool), not at setup, so the error may occur after multiple successful tool calls if the missing tool is rarely invoked. Do NOT retry without fixing the implementation — the model will call the tool again.
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[27][4]
  • chat.completions.runTools · run-tools-stream-termination-error
    error
    WhenThe underlying stream terminates before producing a complete chat completion — same as chat.completions.stream() premature termination. Surfaces when awaiting runner.finalChatCompletion(). Can occur in multi-turn tool loops if network drops during a tool-calling round.
    ThrowsOpenAIError('stream ended without producing a ChatCompletion')
    Required handlingCaller MUST await runner.finalChatCompletion() in a try-catch block. In multi-turn tool loops, stream termination mid-run leaves the conversation in a partial state — the model may have called some tools but not all. On failure: restart the entire tool loop from the beginning — do not attempt to resume from intermediate tool results.
    costhighin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[27][4]
  • files.waitForProcessing · files-wait-for-processing-timeout
    error
    Whenopenai.files.waitForProcessing() called but the file does not reach a terminal status within the maxWait duration (default: 30 minutes / 1,800,000 ms). Each iteration sleeps pollInterval ms (default: 5 seconds) then calls retrieve(). Large file uploads or heavily loaded OpenAI infrastructure can exceed the 30-minute window.
    ThrowsAPIConnectionTimeoutError('Giving up on waiting for file <id> to finish processing after <maxWait> milliseconds.')
    Required handlingCaller MUST wrap waitForProcessing() in try-catch and catch APIConnectionTimeoutError (or its base APIConnectionError) distinctly. On timeout, the caller must decide: (a) resume polling with a fresh call to waitForProcessing() using a custom maxWait, (b) fall back to asynchronous notification, or (c) surface a user-facing error. Do NOT silently ignore the timeout — the file may still be processing and vector store operations that depend on it will fail with NotFoundError or return empty results if the file is not yet indexed. Pass a custom maxWait for large files (>100 MB): maxWait: 2 * 60 * 60 * 1000
    costmediumin prodimmediate exceptionusers seelost transactionvisibilityvisible
    Sources[11][4]
  • files.waitForProcessing · files-wait-for-processing-error-status-unchecked
    error
    Whenopenai.files.waitForProcessing() returns (does NOT throw) when the file status reaches 'error'. The returned FileObject has status='error' and a populated error field. Callers that do not check the returned object's status field silently proceed with an errored, unprocessed file — causing downstream vector store queries to return empty or partial results.
    Throwsnone — returns FileObject with status='error' and populated error.message
    Required handlingCaller MUST check the returned FileObject.status after awaiting: const file = await openai.files.waitForProcessing(fileId); if (file.status === 'error') { throw new Error(`File processing failed: ${file.error?.message}`); } The error field (if present) contains a machine-readable code and human-readable message from the OpenAI platform about why processing failed. Common causes: unsupported file format, file too large for the model, corrupted binary content. Do NOT use the file for vector store queries if status !== 'processed'.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[11]
  • files.delete · files-delete-not-found
    warning
    Whenopenai.files.delete(fileId) called with a fileId that does not exist, has already been deleted, or belongs to a different project/organization. This is the most common failure in cleanup flows where file IDs are cached and the file was already removed by another process or expired. Also thrown if the fileId references a file from a previous API key or org.
    ThrowsNotFoundError (HTTP 404)
    Required handlingCaller MUST wrap files.delete() in try-catch. In idempotent cleanup flows, catch NotFoundError and treat it as success: try { await openai.files.delete(fileId); } catch (err) { if (err instanceof OpenAI.NotFoundError) { // Already deleted — acceptable in cleanup flows return; } throw err; } Do NOT silently swallow all errors — only NotFoundError is acceptable to ignore in cleanup. Re-throw AuthenticationError, RateLimitError, and InternalServerError without swallowing.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[11][4]
  • files.content · files-content-no-error-handling
    error
    Whenopenai.files.content(fileId) called without try-catch. The method makes a GET request to /files/{fileId}/content and can throw: (1) NotFoundError (404) — file does not exist, was already deleted, or belongs to a different project/organization; (2) BadRequestError (400) — file purpose does not support content retrieval (e.g., attempting to download a fine-tuning file that is not yet accessible); (3) AuthenticationError (401) — invalid or revoked API key; (4) PermissionDeniedError (403) — insufficient permissions to access the file; (5) APIConnectionError — network failure during binary download (especially for large files where connection drops mid-stream).
    ThrowsNotFoundError | BadRequestError | AuthenticationError | PermissionDeniedError | APIConnectionError
    Required handlingCaller MUST wrap files.content() in try-catch. The returned Response object must also be error-checked before consuming: try { const response = await openai.files.content(fileId); if (!response.ok) { throw new Error(`File download failed: ${response.status}`); } const buffer = await response.arrayBuffer(); // process buffer... } catch (err) { if (err instanceof OpenAI.NotFoundError) { // File deleted or ID invalid — log and skip } else { throw err; } } For large files: implement timeout handling — APIConnectionTimeoutError can fire for slow network connections downloading large binary files. Do NOT buffer the entire Response in memory for large files — use streaming.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[11][4]
  • files.content · files-content-not-ready
    warning
    Whenopenai.files.content(fileId) called on a file that is still in 'uploaded' status (not yet processed by OpenAI infrastructure) or whose purpose does not support content retrieval at the current API tier. Returns BadRequestError (400). Common in pipeline flows where files.create() is called and content() is called immediately without waiting for processing. Also occurs when the file.purpose is 'fine-tune' and the file is only accessible by the fine-tuning system, not by direct content retrieval.
    ThrowsBadRequestError (HTTP 400)
    Required handlingCaller MUST call files.waitForProcessing(fileId) before files.content(fileId) for files that require processing (purpose='user_data', vision, etc.). After waitForProcessing(), check status === 'processed' before calling content(). For fine-tuning files: do NOT call content() after the fine-tune job completes. Use the fine_tuning.jobs API to retrieve training results instead. Pattern: const file = await openai.files.waitForProcessing(fileId); if (file.status !== 'processed') { throw new Error(`File not ready: ${file.status}`); } const content = await openai.files.content(fileId);
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[11][4]
  • conversations.items.delete · conversations-items-delete-no-error-handling
    error
    Whenopenai.conversations.items.delete(itemId, params) called without try-catch. Can throw: (1) NotFoundError (404) — the itemId or conversation_id does not exist, has already been deleted, or belongs to a different project/organization; (2) UnprocessableEntityError (422) — malformed itemId or missing required params; (3) RateLimitError (429) — conversation mutation rate limit exceeded (common in agent loops that delete and re-add items rapidly); (4) AuthenticationError (401) — invalid or revoked API key. This is a critical operation in agent context window management flows — an unhandled NotFoundError will crash the agent loop entirely.
    ThrowsNotFoundError | UnprocessableEntityError | RateLimitError | AuthenticationError
    Required handlingCaller MUST wrap conversations.items.delete() in try-catch. In agent context management flows, treat NotFoundError as an expired conversation signal — rebuild the conversation from scratch: try { await openai.conversations.items.delete(itemId, { conversation_id }); } catch (err) { if (err instanceof OpenAI.NotFoundError) { // Conversation or item expired — rebuild conversation context await rebuildConversation(); return; } throw err; } For agent loops with high item mutation rates: implement exponential backoff for RateLimitError. The conversation mutation rate limit is separate from the completions rate limit. Do NOT silently swallow all errors — only NotFoundError is safe to handle as a recoverable condition; re-throw all others.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[25][4]
  • beta.chatkit.sessions.create · chatkit-sessions-create-no-error-handling
    error
    Whenopenai.beta.chatkit.sessions.create() called without try-catch. The ChatKit API is a beta endpoint requiring special access. Throws on: (1) AuthenticationError (401) — invalid or revoked API key; (2) PermissionDeniedError (403) — organization not enabled for ChatKit beta or insufficient permissions for the specified workflow; (3) NotFoundError (404) — the workflow.id does not exist or is archived; (4) UnprocessableEntityError (422) — invalid user string or malformed params; (5) RateLimitError (429) — per-minute session creation rate limit exceeded.
    ThrowsAuthenticationError | PermissionDeniedError | NotFoundError | UnprocessableEntityError | RateLimitError
    Required handlingCaller MUST wrap beta.chatkit.sessions.create() in try-catch. This is typically a server-side API route handler — errors must be caught and returned as HTTP error responses rather than crashing the handler. Distinguish PermissionDeniedError (403) — which indicates beta access is not granted and requires contacting OpenAI — from NotFoundError (404) which indicates a misconfigured workflow ID (fix in application config). The returned client_secret MUST be treated as a short-lived credential: do not cache or reuse it across requests; create a new session per user interaction. The session expires after expires_after seconds (default: 600).
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[28][4]
  • beta.chatkit.sessions.create · chatkit-sessions-create-secret-expired
    error
    WhenThe ChatSession.client_secret is cached and reused across requests after the session expires (default: 10 minutes). Expired sessions cause the frontend to receive authentication failures when attempting to use the client_secret. This is a silent failure pattern: the backend route succeeds (200 OK) because it returns a cached session, but the frontend immediately fails when using it.
    Throwsnone — client_secret silently fails on frontend; no exception thrown server-side
    Required handlingServer-side session creation routes MUST create a fresh session per user request — do NOT cache client_secret values. Each call to beta.chatkit.sessions.create() must happen immediately before the secret is sent to the frontend. Do NOT store client_secret in a database or cache. Set an appropriate expires_after value based on your UI's expected response time: if users may take >10 minutes to act after receiving the secret, increase expires_after or implement session refresh logic.
    costmediumin prodsilent failureusers seeauthentication failurevisibilitysilent
    Sources[28]
  • beta.chatkit.sessions.cancel · chatkit-sessions-cancel-no-error-handling
    error
    Whenopenai.beta.chatkit.sessions.cancel(sessionId) called without try-catch. Can throw: (1) NotFoundError (404) — session has already expired (TTL exceeded) or was already cancelled by a prior call; session IDs that are stale or belong to a different org/project also throw 404; (2) AuthenticationError (401) — invalid or revoked API key; (3) PermissionDeniedError (403) — insufficient permissions to cancel this session (e.g., cross-organization session ID); (4) UnprocessableEntityError (422) — malformed sessionId format. In session cleanup flows (user logout, timeout handling), the most likely scenario is that the session already expired — and an uncaught NotFoundError will crash the cleanup handler.
    ThrowsNotFoundError | AuthenticationError | PermissionDeniedError | UnprocessableEntityError
    Required handlingCaller MUST wrap beta.chatkit.sessions.cancel() in try-catch. In session cleanup and logout flows, NotFoundError should be treated as an acceptable result — the session is already inactive: try { await openai.beta.chatkit.sessions.cancel(sessionId); } catch (err) { if (err instanceof OpenAI.NotFoundError) { // Session already expired or cancelled — no action needed return; } throw err; } Do NOT silently swallow all errors — only NotFoundError is safe to treat as a no-op. Re-throw AuthenticationError and PermissionDeniedError as these indicate infrastructure problems. Important: cancellation is immediate and irreversible. Do NOT call cancel() unless you intend to permanently invalidate the session's client_secret.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[28][4]
  • beta.chatkit.sessions.cancel · chatkit-sessions-cancel-already-expired
    warning
    Whenbeta.chatkit.sessions.cancel() is called after the session has naturally expired (default TTL: 10 minutes). The session was never explicitly cancelled but has timed out. This is a silent race condition in logout and cleanup flows: the server assumes the session is active and tries to cancel it, but the TTL has already elapsed. NotFoundError (404) is thrown. Common in flows that store session IDs for later cleanup — by the time cleanup runs, the session has long since expired.
    ThrowsNotFoundError (HTTP 404)
    Required handlingTrack session creation timestamps and expires_after values alongside the sessionId. In cleanup flows: const sessionAgeMs = Date.now() - session.createdAt.getTime(); const sessionTtlMs = (session.expiresAfter ?? 600) * 1000; if (sessionAgeMs < sessionTtlMs) { // Only cancel if within TTL try { await openai.beta.chatkit.sessions.cancel(session.id); } catch (err) { if (!(err instanceof OpenAI.NotFoundError)) throw err; } } // If already expired: nothing to cancel, proceed with local cleanup. For high-throughput systems: use a soft expiry check (TTL minus 30 seconds buffer) to account for clock skew between server and OpenAI infrastructure.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[28][4]
  • images.edit · images-edit-authentication-error
    error
    WhenInvalid or missing API key (401) when calling openai.images.edit().
    ThrowsAuthenticationError with status 401
    Required handlingCaller MUST NOT retry with the same API key. Image-editing endpoints are frequently called from background processing queues where auth failures silently halt the queue. Alert operations team — this is a configuration error.
    costhighin prodsilent failureusers seeservice unavailablevisibilitysilent
    Sources[4][29]
  • images.edit · images-edit-content-policy-violation
    error
    WhenThe source image, mask, or prompt violates OpenAI content policy. Image editing is subject to the same content filter as generation; surfaces as BadRequestError (HTTP 400) with content_policy_violation.
    ThrowsBadRequestError with content_policy_violation
    Required handlingDO NOT retry with the same source image or prompt. Return a user-friendly content-policy error. Log occurrences for compliance monitoring. For user-uploaded images that fail, surface the rejection to the user immediately instead of silently dropping the edit request.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[4][30]
  • images.edit · images-edit-stream-mid-stream-api-error
    error
    Whenopenai.images.edit({stream: true}) returns Stream<ImageEditStreamEvent>. During iteration, the SSE channel can emit an 'error' event mid-stream (provider-side failure after partial_image events have been delivered). core/streaming.js converts this into a synchronous APIError throw inside the for-await loop. Callers that iterate the stream without wrapping the loop in try/catch get an uncaught Promise rejection that crashes the request handler — silently in serverless runtimes, loudly in process-level error handlers.
    ThrowsAPIError (constructed inline via new APIError(undefined, data.error, ...))
    Required handlingCaller MUST wrap the for-await loop in try/catch when iterating the stream. Partial images already delivered to the client UI must be marked as incomplete on error so the user sees a clear failure state instead of a half-rendered image. Pattern: const stream = await openai.images.edit({ image, prompt, stream: true }); try { for await (const event of stream) { if (event.type === 'image_edit.partial_image') { /* update UI */ } if (event.type === 'image_edit.completed') { /* finalize */ } } } catch (err) { if (err instanceof OpenAI.APIError) { /* surface to user, mark incomplete */ } throw err; } DO NOT swallow the error silently — partial_image deliveries already streamed to the client must be invalidated, otherwise the user sees a stuck preview.
    costmediumin proddelayed failureusers seelost transactionvisibilitysilent
    Sources[31][4]
  • images.edit · images-edit-stream-abort-silent-termination
    warning
    Whenopenai.images.edit({stream: true}) iteration exits silently when the underlying AbortController is aborted (user navigated away, server-side request timeout, or explicit stream.controller.abort()). The for-await loop does NOT throw — it returns cleanly without ever emitting an image_edit.completed event. Callers that assume "no throw = success" treat aborted edits as completed and may commit a partial or empty image to user-facing state.
    ReturnsSilent iterator exit — no APIError, no completed event
    Required handlingCaller MUST track completion explicitly — do NOT infer success from the absence of a throw. Pattern: let completed = false; try { for await (const event of stream) { if (event.type === 'image_edit.completed') completed = true; } } catch (err) { /* APIError or network */ } if (!completed) { /* aborted or interrupted — DO NOT commit result */ } For server-side handlers: check req.signal.aborted (or the equivalent for your framework) after the loop and roll back any partial state if true.
    costmediumin prodsilent failureusers seelost transactionvisibilitysilent
    Sources[31][4]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
Source code

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

OpenAI Nark profile - Sources

Official Documentation

Error Handling

API References

Error Types

401 - AuthenticationError

When it occurs: Invalid, missing, or revoked API key

Common causes:

  • API key not set in environment
  • Using wrong API key (test vs production)
  • API key has been revoked
  • Account is not part of an organization
  • Organization has been deleted

Handling strategy:

  • DO NOT retry with the same credentials
  • Verify API key is correct
  • Check organization membership
  • Use environment variables for keys
  • Never hardcode API keys in code
  • Regularly rotate keys for security

Source: https://muneebdev.com/openai-401-error-troubleshooting-guide/

429 - RateLimitError

When it occurs: API rate limit exceeded

Rate limit types:

  • RPM (Requests per minute)
  • RPD (Requests per day)
  • TPM (Tokens per minute)
  • TPD (Tokens per day)
  • IPM (Images per minute) - for DALL-E

Response headers:

  • x-ratelimit-remaining-requests: Requests left in current window
  • x-ratelimit-remaining-tokens: Tokens left in current window
  • x-ratelimit-reset-requests: Time until request limit resets
  • x-ratelimit-reset-tokens: Time until token limit resets

Handling strategy:

  • Implement exponential backoff retry logic
  • Monitor rate limit headers
  • Reduce max_tokens to decrease token consumption
  • Batch requests where possible
  • Implement request queue for sustained traffic
  • Contact OpenAI to request limit increases for production

Automatic Retries: SDK retries 2 times automatically with exponential backoff

Sources:

400 - BadRequestError

When it occurs: Invalid request parameters

Common causes:

  • Invalid model name
  • Temperature out of range (must be 0-2)
  • Invalid message format
  • Token limit exceeded for embeddings
  • Audio file too large (>25 MB for Whisper)
  • Unsupported audio format

Handling strategy:

  • Validate all parameters before making API call
  • Check error.message for specific parameter issue
  • DO NOT retry without fixing the problem
  • Common fixes: verify model names, validate ranges, check input lengths

Source: https://developers.openai.com/api/docs/guides/error-codes/

500+ - APIError (Server Errors)

When it occurs: Internal OpenAI server error

Error codes: 500, 502, 503, 504

Handling strategy:

  • Treat as transient failure
  • Retry with exponential backoff
  • SDK automatically retries 2 times
  • If persistent, check OpenAI status page
  • Log for monitoring - sustained 5xx may indicate outage

Source: https://wizardstool.com/openai-api-http-errors-guide/

Timeout Errors

When it occurs: Request exceeds timeout limit (default: 10 minutes)

Handling strategy:

  • Retry with exponential backoff
  • Reduce max_tokens to speed up generation
  • For streaming, implement client-side timeout handling
  • Configure custom timeout: new OpenAI({ timeout: 20 * 1000 })

Source: https://www.npmjs.com/package/openai

Content Filter Error

When it occurs: Input or output flagged by safety system

Error code: content_filter

Handling strategy:

  • DO NOT retry with same content
  • Return user-friendly error message
  • Consider implementing pre-filtering
  • Review OpenAI usage policies
  • For images, this may be content policy violation

Source: https://developers.openai.com/api/docs/guides/error-codes/

SDK Features

Automatic Retries

The OpenAI SDK automatically retries certain errors 2 times by default with exponential backoff:

  • 429 (Rate Limit)
  • 408 (Request Timeout)
  • 409 (Conflict)
  • 500+ (Server Errors)
  • Connection errors

Configuration:

// Global configuration
const openai = new OpenAI({ maxRetries: 5 });

// Per-request configuration
const completion = await openai.chat.completions.create(
  { model: "gpt-4", messages: [...] },
  { maxRetries: 0 } // Disable retries for this request
);

Source: https://www.npmjs.com/package/openai

Request Timeout

Default timeout: 10 minutes

Configuration:

const openai = new OpenAI({ timeout: 20 * 1000 }); // 20 seconds

TypeScript Support

  • TypeScript >= 4.9 supported
  • Full type definitions for all API endpoints
  • Request params and response fields are fully typed

Common Production Issues

Issue 1: Unexpected API Costs

Severity: High - Financial impact

Problem: Not setting max_tokens can result in unexpectedly long (and expensive) completions

Solution:

  • Always set max_tokens explicitly
  • Set based on expected response length + buffer
  • Monitor token usage via response headers
  • Example: For 400-token responses, set max_tokens around 500

Source: https://developers.openai.com/api/docs/guides/rate-limits/

Issue 2: Rate Limit Errors During Traffic Spikes

Severity: High - Service degradation

Problem: Sudden traffic increases hit rate limits, causing 429 errors

Solutions:

  1. Implement request queue with rate limiting
  2. Use exponential backoff (automatic in SDK)
  3. Monitor x-ratelimit-remaining-* headers
  4. Request limit increase from OpenAI for production apps
  5. Implement caching for repeated queries

Sources:

Issue 3: Hardcoded API Keys

Severity: Critical - Security risk

Problem: API keys committed to version control or hardcoded in source

Solution:

  • Use environment variables exclusively
  • Add .env to .gitignore
  • Rotate keys regularly
  • Use different keys for development and production
  • Never log API keys in error messages

Source: https://muneebdev.com/openai-401-error-troubleshooting-guide/

Issue 4: Not Handling Token Limits

Severity: Medium - Truncated responses

Problem: Hitting token limits causes incomplete responses

Solutions:

  1. For chat: Check finish_reason in response
    • "length" = hit token limit (response truncated)
    • "stop" = normal completion
  2. For embeddings: Chunk input text before API call
    • text-embedding-ada-002: 8191 tokens max
  3. Estimate token count before making request

Source: https://developers.openai.com/api/docs/guides/error-codes/

Issue 5: Streaming Response Errors

Severity: Medium - Incomplete data

Problem: Streaming responses can fail mid-stream

Solution:

  • Implement stream-specific error handling
  • Handle connection drops gracefully
  • Consider client-side timeout for streams
  • Process partial responses when possible

Source: https://www.npmjs.com/package/openai

Security Advisories

Last Checked: 2026-02-23

Notable CVEs

CVE-2024-27564 - Server-Side Request Forgery (SSRF) in ChatGPT infrastructure

CVE-2025-61260 - Codex CLI Command Execution Vulnerability

  • Severity: High
  • Impact: Automatically executed commands from project configs without user approval
  • Affected: Codex CLI tool
  • Status: Patched (August 2025)
  • Source: Vulnerability in OpenAI Coding Agent

CVE-2025-53767 - Azure OpenAI SSRF-based Privilege Escalation

General Security Context

  • 12 critical vulnerabilities found in AI model infrastructure (2025)
  • Risk of unauthorized access and data theft
  • OpenAI launched "Aardvark" security tool to help identify vulnerabilities

Sources:

Best Practices Summary

1. API Key Management

// ✅ CORRECT: Use environment variables
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// ❌ WRONG: Hardcoded key
const openai = new OpenAI({
  apiKey: "sk-...",
});

2. Error Handling Pattern

import OpenAI from "openai";

const openai = new OpenAI();

try {
  const completion = await openai.chat.completions.create({
    model: "gpt-4",
    messages: [{ role: "user", content: "Hello!" }],
    max_tokens: 500, // Always set explicitly
  });

  // Check if response was truncated
  if (completion.choices[0].finish_reason === "length") {
    console.warn("Response was truncated due to token limit");
  }

} catch (error) {
  if (error instanceof OpenAI.APIError) {
    if (error.status === 401) {
      // Authentication error - don't retry
      console.error("Invalid API key");
    } else if (error.status === 429) {
      // Rate limit - SDK auto-retries, but you may want custom logic
      console.warn("Rate limit hit, SDK will retry");
    } else if (error.status >= 500) {
      // Server error - SDK auto-retries
      console.warn("OpenAI server error, retrying");
    }
  }
  throw error;
}

3. Rate Limit Monitoring

const response = await openai.chat.completions.create({...});

// Monitor rate limits from headers
const headers = response.headers;
console.log("Requests remaining:", headers["x-ratelimit-remaining-requests"]);
console.log("Tokens remaining:", headers["x-ratelimit-remaining-tokens"]);

4. Configure Retries and Timeouts

const openai = new OpenAI({
  maxRetries: 3,           // Increase from default 2
  timeout: 30 * 1000,      // 30 seconds instead of 10 minutes
});

Verification Date

Last Verified: 2026-02-23 OpenAI SDK Version: 4.x Documentation Version: Current as of February 2026

Need a different package?
Request a profile