How to Fix 'timeout error during development' in LangChain (TypeScript)
When you see timeout error during development in a LangChain TypeScript app, it usually means one of two things: your request is taking longer than the timeout configured in your code, or the model call is hanging because the chain is waiting on something else first. In practice, this shows up during local development when you add tools, retrievers, or slow async setup and the default timeout is too aggressive.
The fix is usually not “increase the timeout and move on.” You need to identify whether the delay is in model invocation, tool execution, retrieval, or your own app logic.
The Most Common Cause
The #1 cause is wrapping a LangChain call in a timeout that’s shorter than the actual work being done.
This often happens with Promise.race, AbortController, or a framework-level request timeout. The chain itself may be fine, but your wrapper kills it before ChatOpenAI, RunnableSequence, or RetrievalQAChain finishes.
Wrong pattern vs right pattern
| Broken code | Fixed code |
|---|---|
| ```ts | |
| import { ChatOpenAI } from "@langchain/openai"; |
const model = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0, });
async function run() { const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error("timeout error during development")), 3000) );
const result = await Promise.race([ model.invoke("Summarize this long document..."), timeout, ]);
console.log(result); }
run();
|ts
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0, });
async function run() { const result = await model.invoke("Summarize this long document...", { signal: AbortSignal.timeout(15000), });
console.log(result); }
run();
The broken version throws your own generic timeout before LangChain can finish. The fixed version uses an explicit abort signal with a realistic budget.
If you’re using chains, the same issue appears here:
```ts
import { RunnableSequence } from "@langchain/core/runnables";
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const chain = RunnableSequence.from([
async (input: string) => input,
model,
]);
const output = await chain.invoke("Explain vector databases", {
signal: AbortSignal.timeout(20000),
});
Other Possible Causes
1) Slow tool calls inside an agent
If you use AgentExecutor, one slow tool can make the whole run look like a model timeout.
import { AgentExecutor } from "langchain/agents";
// Bad: tool blocks for too long
const tools = [slowDatabaseTool];
const executor = AgentExecutor.fromAgentAndTools(agent, tools);
await executor.invoke(
{ input: "Find customer policy details" },
{ signal: AbortSignal.timeout(5000) }
);
Fix it by timing out the tool separately and logging which tool failed.
const wrappedTool = {
...slowDatabaseTool,
invoke: async (input: string) => {
return Promise.race([
slowDatabaseTool.invoke(input),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("tool timeout")), 3000)
),
]);
},
};
2) Retrievers returning too much data
A VectorStoreRetriever that pulls back huge chunks can make prompt assembly slow enough to hit your timeout.
const retriever = vectorStore.asRetriever({
k: 20, // too high for local dev
});
Reduce retrieval size first.
const retriever = vectorStore.asRetriever({
k: 4,
});
Also check chunk size. If your documents are massive, StuffDocumentsChain can spend time concatenating them before the LLM call even starts.
3) Missing or misconfigured API timeouts
Sometimes the issue is below LangChain. The OpenAI client may be waiting too long on network retries.
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({
model: "gpt-4o-mini",
maxRetries: 6,
});
During development, lower retries so one bad network path does not stall your process.
const model = new ChatOpenAI({
model: "gpt-4o-mini",
maxRetries: 1,
});
4) Async setup running on every request
A common mistake is rebuilding embeddings, loading prompts from disk, or initializing a vector store inside the handler.
export async function handler(req: Request) {
const vectorStore = await PineconeVectorStore.fromExistingIndex(
embeddings,
{ pineconeIndex }
);
return await chain.invoke(await req.text());
}
Move initialization outside the request path.
const vectorStorePromise = PineconeVectorStore.fromExistingIndex(
embeddings,
{ pineconeIndex }
);
export async function handler(req: Request) {
const vectorStore = await vectorStorePromise;
}
How to Debug It
- •
Find where the timeout is thrown
- •If the message is
timeout error during development, that’s probably your own wrapper. - •If you see
AbortErrororRequest timed out, check framework and fetch-level limits. - •If you see
429followed by retries, it’s likely API throttling masquerading as latency.
- •If the message is
- •
Measure each stage separately
- •Time retrieval.
- •Time tool execution.
- •Time LLM invocation.
- •Time response formatting.
Example:
console.time("retrieval"); const docs = await retriever.getRelevantDocuments(query); console.timeEnd("retrieval"); console.time("llm"); const res = await model.invoke(prompt); console.timeEnd("llm"); - •
Turn off concurrency and retries temporarily
- •Set
maxRetries: 1. - •Remove parallel tool calls.
- •Use a single document and small prompt.
- •If it passes now, scale back up until it fails again.
- •Set
- •
Inspect logs for class names
- •
ChatOpenAI - •
RunnableSequence - •
AgentExecutor - •
VectorStoreRetriever
The failing class tells you where to look next. A timeout inside
AgentExecutorusually means a tool; a timeout insideChatOpenAIusually means network, prompt size, or provider latency. - •
Prevention
- •
Keep timeouts explicit and per-layer:
- •request timeout
- •tool timeout
- •LLM timeout
- •
Initialize heavy dependencies once at startup:
- •embeddings clients
- •vector stores
- •retrievers
- •
Start with conservative settings in dev:
new ChatOpenAI({
model: "gpt-4o-mini",
maxRetries: 1,
});
If you’re still stuck after that, reduce the problem to one call:
- •one prompt
- •one retriever query
- •no tools
- •no wrappers
That isolates whether LangChain is actually slow or whether your app is timing itself out.
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