LangChain OpenAI API Fix 6 min read

LangChain OpenAI API Error? Fix AuthenticationError, ChatOpenAI & Model Names

Troubleshoot LangChain + OpenAI errors — AuthenticationError even with a correct key, wrong class (ChatOpenAI vs OpenAI), deprecated model names, chain.invoke() vs chain.run(), structured output failures, and LangSmith tracing slowdowns.

OpenAI live status

OpenAI API — live status

Updated every 5 minutes · Full incident history →

Full status →

Common errors and fixes

1. AuthenticationError — correct key but still failing

The error looks like this:

openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Incorrect API key provided'}}

The two most common causes: the environment variable is named wrong, or it is set after the import. The fix:

import os

# ✅ Set BEFORE importing ChatOpenAI — must be OPENAI_API_KEY exactly
os.environ["OPENAI_API_KEY"] = "sk-..."

from langchain_openai import ChatOpenAI

# ✅ Or pass directly to the constructor (also reads env var as fallback)
llm = ChatOpenAI(model="gpt-4o", api_key="sk-...")

# ❌ Wrong variable names that look right but don't work:
# os.environ["OPENAI_KEY"] = "sk-..."         # missing _API_
# os.environ["openai_api_key"] = "sk-..."      # must be uppercase
  • Verify the key in the OpenAI dashboard — if it starts with sk-proj- it is a project key and requires the project to have API access enabled.
  • In .env files, load with python-dotenv before any imports: from dotenv import load_dotenv; load_dotenv().
  • Shell: export OPENAI_API_KEY=sk-... (Linux/macOS) or $env:OPENAI_API_KEY="sk-..." (PowerShell).

2. ChatOpenAI vs OpenAI — wrong class for chat models

Using the OpenAI class with a chat model name causes an InvalidRequestError because it calls the completions endpoint instead of chat/completions:

from langchain_openai import ChatOpenAI, OpenAI

# ❌ OpenAI class — only for legacy text-completion models (deprecated)
llm = OpenAI(model="gpt-4o")  # InvalidRequestError

# ✅ ChatOpenAI — for ALL current OpenAI chat models
llm = ChatOpenAI(model="gpt-4o")           # recommended, best price/performance
llm = ChatOpenAI(model="gpt-4-turbo")      # if you need a specific turbo version
llm = ChatOpenAI(model="gpt-3.5-turbo")   # cheaper, faster

# ✅ With extra params
llm = ChatOpenAI(
    model="gpt-4o",
    temperature=0.7,
    max_tokens=512,
    streaming=True,        # enables token streaming
)
  • Rule of thumb: if the model name contains "gpt-3.5-turbo", "gpt-4", "gpt-4o", or "o1" — use ChatOpenAI.
  • Old import path from langchain.chat_models import ChatOpenAI is removed in v0.2 — use from langchain_openai import ChatOpenAI.

3. Model name errors — deprecated or misspelled names

OpenAI returns 404 model_not_found for deprecated snapshot names:

# ❌ Deprecated / snapshot names — will 404
ChatOpenAI(model="gpt-4-0314")       # retired snapshot
ChatOpenAI(model="gpt-4-32k")        # no longer available
ChatOpenAI(model="gpt-3.5-turbo-0301")

# ✅ Current aliases (as of 2025) — prefer these
ChatOpenAI(model="gpt-4o")           # points to latest gpt-4o
ChatOpenAI(model="gpt-4o-mini")      # cheaper, fast
ChatOpenAI(model="gpt-4-turbo")      # latest gpt-4-turbo
ChatOpenAI(model="gpt-3.5-turbo")    # legacy but still active
ChatOpenAI(model="o1")               # reasoning model
ChatOpenAI(model="o1-mini")          # cheaper reasoning

Check platform.openai.com/docs/models for the current list — model availability depends on your account tier.

4. chain.run() removed in v0.2 — use chain.invoke()

LangChain v0.2 removed .run() and .__call__() from LCEL chains. The error is AttributeError: 'RunnableSequence' object has no attribute 'run':

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_template("Summarise: {text}")
chain = prompt | llm | StrOutputParser()

# ❌ v0.1 style — removed in v0.2
result = chain.run("My text here")           # AttributeError
result = chain({"text": "My text here"})    # AttributeError

# ✅ v0.2+ style
result = chain.invoke({"text": "My text here"})          # sync
result = await chain.ainvoke({"text": "My text here"})    # async
for chunk in chain.stream({"text": "My text here"}):     # streaming
    print(chunk, end="", flush=True)
  • Legacy LLMChain: if you used LLMChain(llm=..., prompt=...), its .run() still works in v0.2 but is deprecated — it emits a warning and will be removed. Migrate to LCEL.
  • invoke() input: pass a dict matching your prompt's input variables. A single-variable prompt can also accept a plain string: chain.invoke("hello").

5. "Cannot read properties of undefined" — accessing .content on wrong object

When you call llm.invoke() directly (without a parser), it returns an AIMessage object, not a string:

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model="gpt-4o")

# llm.invoke() returns AIMessage, not str
response = llm.invoke("Tell me a joke")
print(response)            # AIMessage(content='Why did the...', ...)
print(response.content)    # ✅ the text string

# With a prompt list
response = llm.invoke([HumanMessage(content="Tell me a joke")])
print(response.content)    # ✅

# Add StrOutputParser to get a plain string from the chain
from langchain_core.output_parsers import StrOutputParser
chain = llm | StrOutputParser()
text = chain.invoke("Tell me a joke")
print(text)  # ✅ plain str
  • Structured output: use llm.with_structured_output(MyPydanticModel) — this returns a Pydantic object, not AIMessage. Do not call .content on its result.
  • JavaScript/TypeScript: @langchain/openai returns the same AIMessage structure — access response.content as a string.

6. Version pinning — langchain vs @langchain/openai (JS/TS)

In Python, langchain and langchain-openai must be from the same release generation. In JS/TS, langchain and @langchain/openai are separate packages with independent versioning:

# Python — check all versions together
pip show langchain langchain-core langchain-openai

# Upgrade everything at once to avoid mismatches
pip install --upgrade langchain langchain-core langchain-openai

# TS/JS — install separately
npm install langchain @langchain/openai @langchain/core

# TS usage
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";

const llm = new ChatOpenAI({ model: "gpt-4o", temperature: 0 });
const prompt = ChatPromptTemplate.fromTemplate("Answer: {question}");
const chain = prompt.pipe(llm).pipe(new StringOutputParser());
const result = await chain.invoke({ question: "What is 2+2?" });
  • Python: langchain[openai] extras syntax is deprecated — install langchain-openai directly.
  • JS/TS peer dep errors: pin @langchain/core to the version that both langchain and @langchain/openai agree on; check with npm ls @langchain/core.

7. LangSmith tracing causing slowdowns

If each chain call takes 2–5 seconds longer than expected, LangSmith tracing is likely adding blocking network calls. Disable or configure it:

# Disable tracing entirely
import os
os.environ["LANGCHAIN_TRACING_V2"] = "false"

# Or unset if you don't need it in production
# del os.environ["LANGCHAIN_TRACING_V2"]

# Enable tracing correctly (all 3 vars required)
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "ls__..."    # from smith.langchain.com
os.environ["LANGCHAIN_PROJECT"] = "my-project" # optional project name

# Suppress tracing for a single call without changing env vars
result = chain.invoke({"input": "hello"}, config={"callbacks": []})
  • Check LangSmith status on Prismix — if LangSmith is degraded, tracing blocks every call until timeout.
  • Background tracing: set LANGCHAIN_TRACING_BACKGROUND=true to make tracing non-blocking (experimental in some versions).

Get an email the next time OpenAI goes down

Outage alerts for OpenAI, straight to your inbox. No account needed, unsubscribe in every email.

Watching more than one service? A free account covers 5 services + a daily digest — and Pro is currently free.

FAQ

Why does LangChain throw AuthenticationError even with the correct OpenAI key?

The most common cause is the environment variable name. It must be exactly OPENAI_API_KEY (uppercase, with _API_). Also, set it before importing ChatOpenAI — the module reads the env var at import time in some versions. If using a .env file, call load_dotenv() before any LangChain imports.

Should I use ChatOpenAI or OpenAI in LangChain?

Use ChatOpenAI for all current OpenAI models (gpt-4o, gpt-4-turbo, gpt-3.5-turbo, o1). The OpenAI class targets the legacy text-completions endpoint (text-davinci-003 etc.) which OpenAI has deprecated. Passing a chat model name to OpenAI() returns an InvalidRequestError.

Which model name should I use — gpt-4, gpt-4o, or gpt-4-turbo?

Use gpt-4o for the best price–performance ratio as of 2025. gpt-4 points to the original GPT-4 (slower, expensive). gpt-4-turbo is the stabilised turbo alias. Snapshot names like gpt-4-0314 are retired and return 404 model_not_found.

Why does LangSmith tracing make my chain slow?

LangSmith tracing is synchronous by default and adds a blocking network call per chain run. Set LANGCHAIN_TRACING_V2=false to disable it, or pass config={"callbacks": []} to suppress tracing for one call. If LangSmith itself is down, every traced call will block until the HTTP timeout.

Monitor related services