@langchain/openai
semver
>=0.1.0postconditions7functions6last verified2026-06-24coverage score86%Postconditions: what we check
- ChatOpenAI.invoke · chat-invoke-network-errorerrorWhenChatOpenAI.invoke() or a chain containing ChatOpenAI is called without wrapping in try-catch. Real-world examples from postiz-app show invoke() called directly without error handling in agent graph nodes.Throws
TimeoutError | openai.RateLimitError | openai.AuthenticationErrorRequired handlingWrap await model.invoke() (or await chain.invoke()) in a try-catch block. Handle TimeoutError (name === 'TimeoutError') for network timeouts, check error.status === 429 for rate limits, error.status === 401 for authentication failures. For agent pipelines, propagate errors to the caller rather than swallowing them.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - embedDocuments · embeddings-network-errorerrorWhenembedDocuments() or embedQuery() is called without wrapping in try-catch. In RAG pipelines these are often called inside vector store constructors which may or may not be protected.Throws
TimeoutError | openai.RateLimitError | openai.AuthenticationErrorRequired handlingWrap await embeddings.embedDocuments() or await embeddings.embedQuery() in a try-catch block. In vector store contexts, ensure the outer operation (e.g., MemoryVectorStore.fromTexts()) is also wrapped.costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilentSources[1] - _call · dalle-network-errorerrorWhenDallEAPIWrapper is instantiated and its invoke() method is called without wrapping in try-catch. Observed in postiz-app's agent.graph.service.ts.Throws
TimeoutError | openai.BadRequestError | openai.RateLimitErrorRequired handlingWrap await dalle.invoke(prompt) in a try-catch block. Handle content policy violations (HTTP 400 with 'content_policy_violation' in message) separately from network errors. Log failures and return a fallback or rethrow with context.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - ChatOpenAI.stream · stream-connection-errorerrorWhenawait model.stream(input) is called without try-catch. Connection errors — auth failure, rate limiting, invalid model, or network timeout — occur before any chunks are received and throw at the await model.stream() call site. This is a separate error vector from mid-stream failures.Throws
TimeoutError (name === 'TimeoutError', wraps APIConnectionTimeoutError) — connection timeout before stream established. openai.AuthenticationError (status === 401, lc_error_code: 'MODEL_AUTHENTICATION') — invalid or missing OPENAI_API_KEY. openai.RateLimitError (status === 429, lc_error_code: 'MODEL_RATE_LIMIT') — API rate limit exceeded at request time. openai.NotFoundError (status === 404, lc_error_code: 'MODEL_NOT_FOUND') — invalid model name. ContextOverflowError (extends Error, from @langchain/core/errors) — input exceeds context window; thrown when error message includes 'context_length_exceeded', 'exceeds the context window', or 'maximum context length'. All confirmed from wrapOpenAIClientError() in dist/utils/client.js source.Required handlingWrap await model.stream(input) in try-catch: try { const stream = await model.stream(input); for await (const chunk of stream) { process.stdout.write(chunk.content); } } catch (error) { if (error.name === 'TimeoutError') { console.error('Stream connection timed out'); } else if (error.lc_error_code === 'MODEL_RATE_LIMIT' || error.status === 429) { console.error('Rate limited — retry with backoff'); } else if (error.lc_error_code === 'MODEL_AUTHENTICATION' || error.status === 401) { console.error('Invalid API key'); } else if (error instanceof ContextOverflowError) { console.error('Input too long — reduce context'); } throw error; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - ChatOpenAI.stream · stream-iteration-errorerrorWhenThe for-await-of loop iterating over the stream returned by model.stream() is not wrapped in try-catch. Mid-stream network failures — connection drops, server disconnects, read timeouts — throw during iteration, not during the initial await model.stream() call. A try-catch around await model.stream() alone will NOT catch these errors.Throws
Same error types as stream-connection-error but thrown during iteration: TimeoutError (name === 'TimeoutError') — connection dropped mid-stream. openai.APIConnectionError — TCP connection lost while receiving chunks. These are NOT caught by a try-catch placed only around await model.stream().Required handlingThe try-catch must wrap BOTH the stream() call AND the for-await-of loop: // ❌ WRONG — catches connection errors but NOT mid-stream failures: const stream = await model.stream(input); // only this line is protected for await (const chunk of stream) { // throws here are NOT caught process.stdout.write(chunk.content); } // ✅ CORRECT — catches all streaming errors: try { const stream = await model.stream(input); for await (const chunk of stream) { process.stdout.write(chunk.content); } } catch (error) { console.error('Streaming failed:', error); throw error; } In Next.js streaming API routes, use ReadableStream with proper error handling rather than relying on try-catch implicitly closing the response.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - ChatOpenAI.moderateContent · moderation-network-errorerrorWhenmodel.moderateContent(text) is called without try-catch in a content safety gate. If the OpenAI Moderation API is unavailable (rate limit, auth failure, or network error), the call throws and the safety check is skipped entirely — allowing unmoderated content to proceed unless the caller handles the error as a blocking failure.Throws
TimeoutError (name === 'TimeoutError') — API connection timed out. openai.AuthenticationError (status === 401, lc_error_code: 'MODEL_AUTHENTICATION') — invalid or missing OPENAI_API_KEY; moderation silently skipped if not caught. openai.RateLimitError (status === 429, lc_error_code: 'MODEL_RATE_LIMIT') — moderation API rate limited; high-volume content pipelines are most affected. openai.InternalServerError (status === 5xx) — OpenAI service unavailable. All confirmed from wrapOpenAIClientError() in dist/utils/client.js and dist/chat_models/base.js moderateContent() source.Required handlingCaller MUST wrap moderateContent() in try-catch and treat API failures as blocking errors, not silent passes. The safety consequence of swallowing errors (allowing unmoderated content) is more severe than service downtime. try { const moderation = await model.moderateContent(userText); if (moderation.results[0].flagged) { return { error: 'Content policy violation', flagged: true }; } } catch (error) { // Moderation API failed — fail safe: block the content console.error('Moderation API unavailable:', error); return { error: 'Content moderation unavailable', flagged: true }; // Alternative: rethrow to surface as 503 to caller } DO NOT default to allowing content on moderation failure — this creates a bypass vector where attackers can exhaust the moderation rate limit to force content policy bypass.costhighin prodsilent failureusers seesecurity breachvisibilitysilent - OpenAI.invoke · llm-invoke-network-errorerrorWhenOpenAI.invoke() (or .generate(), or .stream() on the legacy LLM class) is called without wrapping in try-catch. The legacy LLM class is still exported in @langchain/openai@1.5.3 and re-exported as AzureOpenAI for Azure deployments. Error vectors are identical to ChatOpenAI.invoke because both paths funnel through wrapOpenAIClientError().Throws
TimeoutError (name === 'TimeoutError', wraps APIConnectionTimeoutError) — connection timeout before completion returned. openai.AuthenticationError (status === 401, lc_error_code: 'MODEL_AUTHENTICATION') — invalid or missing OPENAI_API_KEY (or AZURE_OPENAI_API_KEY for AzureOpenAI). openai.RateLimitError (status === 429, lc_error_code: 'MODEL_RATE_LIMIT') — API rate limit exceeded. openai.NotFoundError (status === 404, lc_error_code: 'MODEL_NOT_FOUND') — invalid model name (legacy text-completion models like gpt-3.5-turbo-instruct are still supported but newer models route here through deprecation paths). ContextOverflowError (extends Error, from @langchain/core/errors) — input exceeds context window. All confirmed from wrapOpenAIClientError().Required handlingWrap await llm.invoke(prompt) (or await llm.generate([prompts]), or the stream() call site) in a try-catch block. Handle error.lc_error_code values for normalized error routing, or fall back to error.status checks. For AzureOpenAI specifically, also handle deployment-not-found errors (HTTP 404 with 'DeploymentNotFound' in message) as a distinct case from MODEL_NOT_FOUND. try { const llm = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); const result = await llm.invoke("Tell me a joke."); return result; } catch (error) { if (error.name === 'TimeoutError') { console.error('LLM timeout'); } else if (error.lc_error_code === 'MODEL_RATE_LIMIT') { console.error('Rate limited — retry with backoff'); } else if (error.lc_error_code === 'MODEL_AUTHENTICATION') { console.error('Invalid API key'); } throw error; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
Official documentation
- [4]platform.openai.com/docs/api-reference/moderationsCreate
Source code
- [2]github.com/langchain-ai/langchainjs/bloblangchain-ai/langchainjs · completions.ts
- [3]github.com/langchain-ai/langchainjs/bloblangchain-ai/langchainjs · client.ts
- [5]github.com/langchain-ai/langchainjs/bloblangchain-ai/langchainjs · base.ts
- [6]github.com/langchain-ai/langchainjs/bloblangchain-ai/langchainjs · llms.ts
Issues & pull requests
- [1]github.com/langchain-ai/langchainjs/issueslangchain-ai/langchainjs issue #1547
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources — @langchain/openai
URLs Fetched
| URL | Date | Summary |
|---|---|---|
| https://github.com/langchain-ai/langchainjs/issues/1547 | 2026-04-02 | "Catching the original OpenAI error" — confirms wrapOpenAIClientError properly surfaces OpenAI SDK errors; issue closed Sept 2023 after fix |
| https://github.com/langchain-ai/langchainjs/security/advisories/GHSA-r399-636x-v7f6 | 2026-04-02 | CVE-2025-68665 (CVSS 8.6) — serialization injection in @langchain/core < 1.1.8; affects loads/dumps APIs not direct chat invocation |
| https://docs.langchain.com/oss/javascript/langchain/overview | 2026-04-02 | General LangChain.js overview; no error-handling specifics |
Package Source Examined
/private/tmp/claude-501/package/dist/utils/client.js— actualwrapOpenAIClientErrorimplementation listing all HTTP error codes and their mapped error types/private/tmp/claude-501/package/dist/index.d.ts— full export list/private/tmp/claude-501/package/dist/embeddings.d.ts— OpenAIEmbeddings class signatures/private/tmp/claude-501/package/dist/tools/dalle.d.ts— DallEAPIWrapper class signature/private/tmp/claude-501/package/dist/chat_models/base.d.ts— BaseChatOpenAI types
Real-World Repositories Examined
| Repo | Stars | File | Finding |
|---|---|---|---|
| gitroomhq/postiz-app | 27,547 | libraries/.../agent.graph.service.ts | invoke() called without try-catch |
| gitroomhq/postiz-app | 27,547 | libraries/.../autopost.service.ts | dalle.invoke() called without try-catch |
| developersdigest/llm-answer-engine | 5,021 | app/tools/contentProcessing.tsx | embeddings used inside try-catch (correct) |
Need a different package?
Request a profile