How to Fix 'invalid API key during development' in LangGraph (Python)
When LangGraph throws invalid API key during development, it usually means your app is calling a model provider with a missing, wrong, or inaccessible credential. In practice, this shows up most often when you move from a notebook or local shell into a LangGraph app, and the environment variable is not actually available where the graph runs.
The key detail: LangGraph is usually not the thing rejecting the key. The underlying provider client — often openai, anthropic, or a hosted model wrapper — raises the error while LangGraph is executing a node.
The Most Common Cause
The #1 cause is setting the API key in one place, then running LangGraph in another process that never receives it.
Typical example: you set OPENAI_API_KEY in your terminal, but your app runs through VS Code, Docker, a background worker, or an .env file that never gets loaded.
Broken vs fixed pattern
| Broken | Fixed |
|---|---|
| Reads config too late or not at all | Loads env before creating the model client |
| Assumes shell env is visible everywhere | Explicitly loads .env or passes env into runtime |
| Creates client at import time with missing key | Creates client after env initialization |
# broken.py
from langgraph.graph import StateGraph
from langchain_openai import ChatOpenAI
# This runs immediately at import time.
# If OPENAI_API_KEY is missing here, you'll get:
# openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Incorrect API key provided...'}}
llm = ChatOpenAI(model="gpt-4o-mini")
def call_model(state):
return {"messages": [llm.invoke(state["messages"])]}
# fixed.py
import os
from dotenv import load_dotenv
from langgraph.graph import StateGraph
from langchain_openai import ChatOpenAI
load_dotenv() # make sure .env is loaded before client creation
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise RuntimeError("OPENAI_API_KEY is missing")
llm = ChatOpenAI(model="gpt-4o-mini", api_key=api_key)
def call_model(state):
return {"messages": [llm.invoke(state["messages"])]}
If you are using LangGraph with an OpenAI-compatible endpoint, the same issue applies to base_url and provider-specific keys. A missing LANGSMITH_API_KEY or ANTHROPIC_API_KEY can fail later in a node and look like a LangGraph problem.
Other Possible Causes
1) Wrong environment variable name
A lot of people set API_KEY or OPENAI_KEY and assume the SDK will find it. It won’t.
# wrong
os.environ["API_KEY"] = "sk-..."
llm = ChatOpenAI(model="gpt-4o-mini")
# right
os.environ["OPENAI_API_KEY"] = "sk-..."
llm = ChatOpenAI(model="gpt-4o-mini")
For Anthropic:
ANTHROPIC_API_KEY=...
For OpenAI-compatible providers, check the exact env var expected by that SDK.
2) .env file exists but is never loaded
If you rely on .env, Python does nothing with it unless you load it.
# broken
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# fixed
from dotenv import load_dotenv
load_dotenv()
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
This bites especially hard in LangGraph because graph nodes may run long after startup, so the failure looks disconnected from the real cause.
3) Key exists locally, but not inside Docker / CI / deployment
Your laptop has the key; your container doesn’t.
# docker-compose.yml
services:
app:
build: .
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
If ${OPENAI_API_KEY} is empty on the host machine, Docker passes an empty value into the container. In Kubernetes or CI, define the secret explicitly instead of assuming local shell inheritance.
4) Client initialized before environment variables are set
This happens when imports are ordered badly.
# broken_app.py
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini") # created too early
import os
os.environ["OPENAI_API_KEY"] = "sk-..." # too late
# fixed_app.py
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
In larger LangGraph apps, keep secret loading in your entrypoint, not buried inside modules that get imported unpredictably.
How to Debug It
- •
Print what the process actually sees
import os print("OPENAI_API_KEY set:", bool(os.getenv("OPENAI_API_KEY"))) print("Key prefix:", os.getenv("OPENAI_API_KEY", "")[:6])If this prints
False, stop looking at LangGraph and fix config first. - •
Reproduce outside LangGraph Call the model directly before wiring it into a graph.
from langchain_openai import ChatOpenAI llm = ChatOpenAI(model="gpt-4o-mini") print(llm.invoke("ping"))If this fails with
openai.AuthenticationError, your graph is innocent. - •
Check where the graph runs Confirm whether execution happens in:
- •local shell
- •Jupyter notebook
- •Docker container
- •background worker / queue consumer
- •deployed runtime
Each one can have different environment variables.
- •
Inspect the exact exception Common messages include:
- •
openai.AuthenticationError: Error code: 401 - •
anthropic.AuthenticationError - •
Invalid API key provided - •
Could not authenticate with provided credentials
The class name tells you which provider rejected the request.
- •
Prevention
- •Load secrets once at process startup with
load_dotenv()or your platform’s secret manager. - •Create model clients after env initialization, not at module import time.
- •Add a startup check that fails fast if required keys are missing:
required = ["OPENAI_API_KEY"] missing = [k for k in required if not os.getenv(k)] if missing: raise RuntimeError(f"Missing secrets: {missing}")
If you’re still stuck after checking env loading and deployment config, log the provider client construction path. In LangGraph projects, these failures are almost always caused by runtime configuration, not by the graph itself.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit