LangChain and LlamaIndex Errors That Aren't About Your Prompt
No module named 'langchain_openai'or a failingfrom langchain.chat_models import ChatOpenAI: runpip install -U langchain-openaiand importfrom langchain_openai import ChatOpenAI.from llama_index import VectorStoreIndexfails: import fromllama_index.core.ServiceContextstill imports but raises when used; setSettings.embed_model/Settings.llminstead.Input should be an instance of Runnable: you passed a string, function or raw client asllm=. Pass a chat model object, or writeprompt | llm | parser.- Embedding dimension errors: the query embedding model is not the one that built the index. Pin it and save its dimension next to the index.
Most LangChain and LlamaIndex errors people ask about have nothing to do with the LLM itself. They are packaging problems and state mismatches. langchain used to be one large install; it is now a small core plus separate provider packages, and each major release moved imports again. Tutorials written at different points in that history each break in their own way, which is why the same line of code gives three different errors below depending on the installed version.
Reproduced
Every row was run in a fresh venv. No real API key was used: the OpenAI rows stop at the credentials or 401 error, which is expected.
| What I ran | Exact error or output | Fix that worked |
|---|---|---|
from langchain_openai import ChatOpenAI (langchain 1.4.2, no langchain-openai) | ModuleNotFoundError: No module named 'langchain_openai' | pip install -U langchain-openai (installed 1.6.6); import then succeeded |
from langchain.chat_models import ChatOpenAI (langchain 1.4.2) | ImportError: cannot import name 'ChatOpenAI' from 'langchain.chat_models' | from langchain_openai import ChatOpenAI |
| Same import on langchain 0.3.27 without langchain-community | ModuleNotFoundError: No module named 'langchain_community' | Same as above (installing langchain-community only moves you to a deprecated path) |
| Same import on langchain 0.1.20 | Works, with LangChainDeprecationWarning: Importing chat models from langchain is deprecated. | Migrate before upgrading |
from langchain_community.chat_models import ChatOpenAI (community 0.4.2) | ImportError: cannot import name 'ChatOpenAI' from 'langchain_community.chat_models' | from langchain_openai import ChatOpenAI |
from langchain.llms import OpenAI / from langchain.chains import LLMChain (1.4.2) | No module named 'langchain.llms' / No module named 'langchain.chains' | langchain_openai; LCEL, or from langchain_classic.chains import LLMChain |
from langchain.embeddings import OpenAIEmbeddings (1.4.2) | ImportError: cannot import name 'OpenAIEmbeddings' from 'langchain.embeddings' | from langchain_openai import OpenAIEmbeddings |
LLMChain(llm="gpt-4o", prompt=p) (langchain-classic 1.0.8) | ValidationError: 2 validation errors for LLMChain ... Input should be an instance of Runnable | Pass a chat model object; LLMChain(llm=model, prompt=p) returned {'text': 'a summary'} with a fake model |
| Same call on langchain 0.1.20, pydantic 1.10.26 | pydantic.error_wrappers.ValidationError: 2 validation errors for LLMChain ... instance of Runnable expected | Same |
prompt | "not runnable" | TypeError: Expected a Runnable, callable or dict.Instead got an unsupported type: <class 'str'> | Pipe Runnables only; prompt | model | StrOutputParser() returned 'a summary' |
from llama_index import VectorStoreIndex (llama-index-core 0.14.25) | ImportError: cannot import name 'VectorStoreIndex' from 'llama_index' (unknown location) | from llama_index.core import VectorStoreIndex |
ServiceContext.from_defaults() | ValueError: ServiceContext is deprecated. Use llama_index.settings.Settings instead, ... | Settings.embed_model = ... |
Index built with MockEmbedding(embed_dim=768), persisted, reloaded and queried with 1536 | ValueError: shapes (1536,) and (768,) not aligned: 1536 (dim 0) != 768 (dim 0) | Reload with a 768-dim embed model: retrieval returned both nodes |
| Same, with a Chroma collection | chromadb.errors.InvalidArgumentError: Collection expecting embedding with dimension of 768, got 1536 | Same |
LangChain InMemoryVectorStore, 768-dim fake embeddings in, 1536 out | ValueError: Number of columns in X and Y must be the same. X has shape (1, 1536) and Y has shape (2, 768). | Same embedding object for writes and queries |
ModuleNotFoundError: no module named langchain_openai (or langchain_community)
from langchain.chat_models import ChatOpenAI # old path
llm = ChatOpenAI(model="gpt-4o")
What this line does depends on the installed langchain. On 1.4.2:
ImportError: cannot import name 'ChatOpenAI' from 'langchain.chat_models' (.../site-packages/langchain/chat_models/__init__.py)
On 0.3.27, where the old path was a redirect into the community package:
ModuleNotFoundError: No module named 'langchain_community'
And the error in this section's title is what you get when the new import is already in the code but the package is not installed:
ModuleNotFoundError: No module named 'langchain_openai'
All three have the same fix. Provider integrations ship as their own pip packages (langchain-openai, langchain-anthropic and so on), and langchain_community 0.4.2 no longer exports ChatOpenAI at all, so installing community is not a detour that works:
pip install -U langchain-openai
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
llm = ChatOpenAI(model="gpt-4o")
With no key set, constructing the model fails with openai.OpenAIError: Missing credentials. Please pass an `api_key`, ...; with a fake key, .invoke() reaches the API and returns a 401 invalid_api_key. Either one means the import problem is solved.
For integrations without a dedicated package (some vector stores and document loaders), pip install -U langchain-community and import from langchain_community directly. Importing it on 0.4.2 prints a DeprecationWarning that the package "is being sunset and is no longer actively maintained", so prefer a standalone integration package when one exists. LLMChain and the other legacy chains moved to langchain-classic (from langchain_classic.chains import LLMChain); langchain 1.4.2 does not depend on it, so install it yourself if you need it.
"Input should be an instance of Runnable" in LLMChain
On current versions (pydantic v2):
pydantic_core._pydantic_core.ValidationError: 2 validation errors for LLMChain
llm.is-instance[Runnable]
Input should be an instance of Runnable [type=is_instance_of, input_value='gpt-4o', input_type=str]
For further information visit https://errors.pydantic.dev/2.13/v/is_instance_of
llm.is-instance[Runnable]
Input should be an instance of Runnable [type=is_instance_of, input_value='gpt-4o', input_type=str]
The older wording, from langchain 0.1.20 on pydantic 1.10.26:
pydantic.error_wrappers.ValidationError: 2 validation errors for LLMChain
llm
instance of Runnable expected (type=type_error.arbitrary_type; expected_arbitrary_type=Runnable)
llm
instance of Runnable expected (type=type_error.arbitrary_type; expected_arbitrary_type=Runnable)
Both came from the same call, LLMChain(llm="gpt-4o", prompt=prompt), and a plain Python function gave the same error. The llm field accepts any Runnable, and every LangChain chat model is one, so a real ChatOpenAI or fake chat model passes validation. The error means the thing you passed is not a LangChain model at all: a model name string, a function, or a raw openai.OpenAI() client. Pass the model object. Better, drop LLMChain (deprecated since 0.1.17, and its warning says it "will be removed in 2.0.0") and compose:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("Summarize: {text}")
llm = ChatOpenAI(model="gpt-4o")
parser = StrOutputParser()
chain = prompt | llm | parser
result = chain.invoke({"text": "..."})
With FakeListChatModel(responses=["a summary"]) in place of ChatOpenAI, this chain returned 'a summary'. The | operator has its own version of the same check: piping a string gave TypeError: Expected a Runnable, callable or dict.Instead got an unsupported type: <class 'str'> (the missing space after the period is in the real message). Plain functions are allowed there and get wrapped automatically, which is not the case for LLMChain(llm=...).
LlamaIndex: from llama_index import ... and ServiceContext
With llama-index-core 0.14.25, the top-level package is only a namespace:
ImportError: cannot import name 'VectorStoreIndex' from 'llama_index' (unknown location)
Import from llama_index.core instead. Integrations are separate packages here too: from llama_index.embeddings.openai import OpenAIEmbedding gave No module named 'llama_index.embeddings' until pip install llama-index-embeddings-openai.
ServiceContext is a trap because the import still succeeds. The failure comes when you call it:
ValueError: ServiceContext is deprecated. Use llama_index.settings.Settings instead, or pass in modules to local functions/methods/interfaces.
Set the global defaults on Settings (Settings.llm, Settings.embed_model), or pass embed_model= directly to the index.
Embedding dimension mismatch between index and query
from llama_index.core import VectorStoreIndex, StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
query_engine = index.as_query_engine()
response = query_engine.query("What does the document say about pricing?")
To reproduce without an API, I built and persisted an index with MockEmbedding(embed_dim=768), then reloaded it with Settings.embed_model = MockEmbedding(embed_dim=1536) and retrieved. The default in-memory store fails deep inside NumPy:
ValueError: shapes (1536,) and (768,) not aligned: 1536 (dim 0) != 768 (dim 0)
The same setup on a Chroma collection gives a clearer message, because Chroma stores the collection's dimension and checks it:
chromadb.errors.InvalidArgumentError: Collection expecting embedding with dimension of 768, got 1536
LangChain's InMemoryVectorStore behaves the same way with DeterministicFakeEmbedding(size=768) for writes and size 1536 for queries: ValueError: Number of columns in X and Y must be the same. X has shape (1, 1536) and Y has shape (2, 768).
None of these stores records which embedding model wrote the vectors, only (at best) their size. So if the index was built with one model and the environment now defaults to another (a different model, or an OpenAI text-embedding-3 model with a different dimensions value), nothing complains until the first query. Two models with the same dimension will not error at all; they just return poor matches. Pin the model explicitly before loading:
from llama_index.core import Settings, StorageContext, load_index_from_storage
from llama_index.embeddings.openai import OpenAIEmbedding
# Must match what built the index, not whatever the default is today
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small", dimensions=768)
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
In the mock run, reloading with a 768-dim embed model made retrieval work again and return both stored nodes. The OpenAIEmbedding line above was only constructed (it reports dimensions 768), not called, since that needs a key.
To stop relying on memory, write the model name and dimension next to the persisted index and check it before querying:
import json
# at build time
json.dump({"model": "text-embedding-3-small", "embed_dim": 768},
open("storage/embed_model.json", "w"))
# at query time
meta = json.load(open("storage/embed_model.json"))
dim = len(Settings.embed_model.get_query_embedding("dimension check"))
if dim != meta["embed_dim"]:
raise RuntimeError(f"index built with {meta['embed_dim']}-dim embeddings, "
f"current embed model returns {dim}")
With the 1536-dim mock active, that check stopped with index built with 768-dim embeddings, current embed model returns 1536 before any retrieval ran. This kind of bug rarely shows up in a single notebook where the default never changes. It appears when an index is shared across environments or reloaded months later after a default model changed.