LangChain simplifies LLM development but has its own set of challenges. This guide covers common LangChain errors and their solutions.
Error: OutputParserException
Symptom:
langchain.schema.output_parser.OutputParserException:
Could not parse LLM output: `I'll help you with that...`Cause: LLM didn't follow expected output format.
Solution 1 - Use output fixing parser:
from langchain.output_parsers import OutputFixingParser
from langchain.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from pydantic import BaseModel
class Response(BaseModel):
answer: str
confidence: float
# Base parser
parser = PydanticOutputParser(pydantic_object=Response)
# Wrap with fixing parser
fixing_parser = OutputFixingParser.from_llm(
parser=parser,
llm=ChatOpenAI(temperature=0)
)
# Now it will auto-fix malformed outputs
result = fixing_parser.parse(llm_output)Solution 2 - Use retry parser:
from langchain.output_parsers import RetryWithErrorOutputParser
retry_parser = RetryWithErrorOutputParser.from_llm(
parser=parser,
llm=ChatOpenAI(temperature=0),
max_retries=3
)Solution 3 - Simplify output format:
from langchain.output_parsers import StrOutputParser
# Instead of complex structured output
chain = prompt | llm | StrOutputParser()
# Parse the string manually if needed
def parse_response(text):
# Custom parsing logic
return {"answer": text.strip()}Error: Chain Invoke Returns None
Symptom:
result = chain.invoke({"input": "Hello"})
# result is None or emptySolution 1 - Check chain construction:
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
# ❌ Wrong - missing output parser
chain = prompt | llm
# ✅ Correct - include output parser
chain = prompt | llm | StrOutputParser()
# Debug chain
print(chain) # See chain structureSolution 2 - Debug intermediate steps:
from langchain.callbacks import StdOutCallbackHandler
# Enable verbose output
chain.invoke(
{"input": "Hello"},
config={"callbacks": [StdOutCallbackHandler()]}
)Solution 3 - Check prompt variables:
prompt = ChatPromptTemplate.from_template(
"Answer this: {question}" # Variable name matters!
)
# ❌ Wrong variable name
chain.invoke({"input": "Hello"}) # Should be "question"
# ✅ Correct
chain.invoke({"question": "Hello"})
# Check required variables
print(prompt.input_variables) # ['question']Error: Vector Store Connection Failed
Symptom:
chromadb.errors.InvalidCollectionException: Collection not found
pinecone.exceptions.NotFoundException: Index not foundSolution 1 - Initialize vector store correctly:
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# Create or load existing collection
vectorstore = Chroma(
collection_name="my_collection",
embedding_function=OpenAIEmbeddings(),
persist_directory="./chroma_db" # Persist to disk
)
# Add documents
vectorstore.add_documents(documents)
# Persist changes
vectorstore.persist()Solution 2 - Handle Pinecone index:
from pinecone import Pinecone, ServerlessSpec
from langchain_pinecone import PineconeVectorStore
# Initialize Pinecone
pc = Pinecone(api_key="your-api-key")
# Check if index exists
if "my-index" not in pc.list_indexes().names():
pc.create_index(
name="my-index",
dimension=1536, # OpenAI embeddings dimension
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
# Connect to index
vectorstore = PineconeVectorStore(
index_name="my-index",
embedding=OpenAIEmbeddings()
)Solution 3 - Debug embeddings:
# Test embeddings separately
embeddings = OpenAIEmbeddings()
test_embedding = embeddings.embed_query("test")
print(f"Embedding dimension: {len(test_embedding)}") # Should be 1536 for OpenAIError: Agent Maximum Iterations Exceeded
Symptom:
AgentExecutorIterationLimit: Agent stopped due to iteration limit or time limitCause: Agent stuck in a loop or task too complex.
Solution 1 - Increase limits carefully:
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
max_iterations=15, # Increase from default 10
max_execution_time=60, # Seconds
early_stopping_method="generate" # Let agent generate final answer
)Solution 2 - Add better tool descriptions:
from langchain.tools import Tool
# ❌ Vague description
search_tool = Tool(
name="search",
description="Search for information",
func=search_func
)
# ✅ Clear, specific description
search_tool = Tool(
name="web_search",
description="Search the web for current information. Use this when you need up-to-date facts, news, or data that might not be in your training. Input should be a specific search query.",
func=search_func
)Solution 3 - Use structured agent:
from langchain.agents import create_structured_chat_agent
# Structured agents are more predictable
agent = create_structured_chat_agent(
llm=ChatOpenAI(temperature=0),
tools=tools,
prompt=prompt
)Error: Memory Not Persisting
Symptom:
# Conversation context lost between calls
chain.invoke({"input": "My name is John"})
chain.invoke({"input": "What's my name?"}) # Doesn't rememberSolution 1 - Add memory correctly:
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
memory = ConversationBufferMemory(return_messages=True)
chain = ConversationChain(
llm=ChatOpenAI(),
memory=memory,
verbose=True
)
# Now it remembers
chain.invoke({"input": "My name is John"})
response = chain.invoke({"input": "What's my name?"})
print(response) # "Your name is John"Solution 2 - Use RunnableWithMessageHistory:
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
# Store for sessions
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
chain_with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="input",
history_messages_key="history"
)
# Use with session
response = chain_with_history.invoke(
{"input": "Hi, I'm John"},
config={"configurable": {"session_id": "user123"}}
)Solution 3 - Persist memory to database:
from langchain_community.chat_message_histories import SQLChatMessageHistory
history = SQLChatMessageHistory(
session_id="user123",
connection_string="sqlite:///chat_history.db"
)
# Messages persist across restarts
history.add_user_message("Hello")
history.add_ai_message("Hi there!")Error: Document Loader Failed
Symptom:
ValueError: File type not supported
UnicodeDecodeError: 'utf-8' codec can't decode byteSolution 1 - Use correct loader:
from langchain_community.document_loaders import (
PyPDFLoader,
TextLoader,
CSVLoader,
UnstructuredWordDocumentLoader
)
# PDF files
loader = PyPDFLoader("document.pdf")
# Text with encoding
loader = TextLoader("document.txt", encoding="utf-8")
# CSV
loader = CSVLoader("data.csv")
# Word documents
loader = UnstructuredWordDocumentLoader("document.docx")
docs = loader.load()Solution 2 - Handle encoding errors:
from langchain_community.document_loaders import TextLoader
# Try different encodings
encodings = ["utf-8", "latin-1", "cp1252"]
for encoding in encodings:
try:
loader = TextLoader("document.txt", encoding=encoding)
docs = loader.load()
print(f"Success with {encoding}")
break
except UnicodeDecodeError:
continueError: Retrieval Returns Irrelevant Results
Symptom:
# Query: "What is the refund policy?"
# Returns: documents about shipping insteadSolution 1 - Tune retrieval parameters:
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={
"k": 4, # Number of results
"score_threshold": 0.7 # Minimum similarity
}
)
# Or use MMR for diversity
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={
"k": 4,
"fetch_k": 20, # Fetch more, then filter
"lambda_mult": 0.5 # Diversity vs relevance
}
)Solution 2 - Improve chunking:
from langchain.text_splitter import RecursiveCharacterTextSplitter
# Better chunking preserves context
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200, # Overlap prevents context loss
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = splitter.split_documents(documents)Solution 3 - Add metadata filtering:
# Add metadata when indexing
for doc in documents:
doc.metadata["category"] = "refund_policy"
vectorstore.add_documents(documents)
# Filter during retrieval
retriever = vectorstore.as_retriever(
search_kwargs={
"k": 4,
"filter": {"category": "refund_policy"}
}
)Quick Reference: Common Fixes
| Error | Quick Fix | |-------|-----------| | OutputParserException | Use OutputFixingParser | | Chain returns None | Add StrOutputParser() | | Vector store not found | Check persist_directory | | Agent loops | Improve tool descriptions | | Memory lost | Use ConversationBufferMemory | | Wrong documents | Adjust k and score_threshold |
LangChain Best Practices
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.callbacks import StdOutCallbackHandler
# Production-ready chain
def create_robust_chain():
llm = ChatOpenAI(
temperature=0,
model="gpt-4o",
request_timeout=60,
max_retries=3
)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("human", "{input}")
])
chain = prompt | llm | StrOutputParser()
return chain
# Usage with error handling
chain = create_robust_chain()
try:
result = chain.invoke(
{"input": "Hello"},
config={"callbacks": [StdOutCallbackHandler()]}
)
except Exception as e:
print(f"Chain failed: {e}")Building RAG Applications?
Production RAG systems require careful design. Our team offers:
- RAG architecture consulting
- Vector database optimization
- LLM security audits
- Performance tuning