langchain-ai/langchain · error · ValueError
Number of columns in X and Y must be the same. X has shape {
Error message
Number of columns in X and Y must be the same. X has shape {x.shape} and Y has shape {y.shape}. What it means
cosine_similarity raises this ValueError after converting inputs to numpy arrays when the column dimensions differ: x has shape (n, d1) and y has shape (m, d2) with d1 != d2. Cosine similarity is only defined between vectors of the same dimensionality, and np.dot(x, y.T) (or simd.cdist) would fail or produce nonsense otherwise, so the function validates shapes explicitly and reports both shapes in the message.
Source
Thrown at libs/core/langchain_core/vectorstores/utils.py:88
"NaN found in input arrays, unexpected return might follow",
category=RuntimeWarning,
stacklevel=2,
)
# Check for Inf
if np.any(np.isinf(x)) or np.any(np.isinf(y)):
warnings.warn(
"Inf found in input arrays, unexpected return might follow",
category=RuntimeWarning,
stacklevel=2,
)
if x.shape[1] != y.shape[1]:
msg = (
f"Number of columns in X and Y must be the same. X has shape {x.shape} "
f"and Y has shape {y.shape}."
)
raise ValueError(msg)
if not _HAS_SIMSIMD:
logger.debug(
"Unable to import simsimd, defaulting to NumPy implementation. If you want "
"to use simsimd please install with `pip install simsimd`."
)
x_norm = np.linalg.norm(x, axis=1)
y_norm = np.linalg.norm(y, axis=1)
# Ignore divide by zero errors run time warnings as those are handled below.
with np.errstate(divide="ignore", invalid="ignore"):
similarity: npt.NDArray[np.floating] = np.dot(x, y.T) / np.outer(
x_norm, y_norm
)
if np.isnan(similarity).all():
msg = "NaN values found, please remove the NaN values and try again"
raise ValueError(msg) from None
similarity[np.isnan(similarity) | np.isinf(similarity)] = 0.0
return similarity
View on GitHub (pinned to e32fa9a52e)
Solutions
- Re-embed the side with the wrong dimensionality so both x and y use the same embedding model, then retry.
- Verify dimensions before the call: assert np.asarray(x).shape[1] == np.asarray(y).shape[1].
- If you changed embedding models, rebuild the vector store (delete and re-add all documents with the new embedder) rather than mixing old and new vectors.
- Inspect the shapes reported in the message — the side whose column count does not match your current model's dimension is the stale one.
Example fix
// before query_embs = openai_embedder.embed_queries(queries) # 1536-dim doc_embs = stored_vectors_from_old_model # 1536? no, 3072-dim sim = cosine_similarity(query_embs, doc_embs) # ValueError // after (re-embed docs with the same model) doc_embs = openai_embedder.embed_documents(doc_texts) assert len(query_embs[0]) == len(doc_embs[0]) sim = cosine_similarity(query_embs, doc_embs)
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def check_same_dimension(x, y) -> None:
dx = np.asarray(x).shape[1]
dy = np.asarray(y).shape[1]
if dx != dy:
msg = f"embedding dimension mismatch: x={dx}, y={dy}; re-embed with one model"
raise ValueError(msg) Type guard
import numpy as np
def same_dimension(x: object, y: object) -> bool:
"""True if both inputs are 2-D with equal column counts."""
try:
ax, ay = np.asarray(x), np.asarray(y)
except Exception:
return False
return ax.ndim == 2 and ay.ndim == 2 and ax.shape[1] == ay.shape[1] Try / catch
try:
sim = cosine_similarity(x, y)
except ValueError as e:
if "Number of columns" in str(e):
logger.error("stale embeddings detected (%s); rebuilding index", e)
rebuild_vector_store() # re-embed everything with the current model
else:
raise Prevention
- Record the embedding model name and dimension in the vector store's metadata and verify it on load.
- Never mix embeddings from different models in one store; re-embed the whole corpus when switching models.
- Assert dimension equality before calling cosine_similarity in pipeline code.
- Wrap embedder instantiation in one factory so query-side and document-side always share the same configured model.
When it happens
Trigger: Calling cosine_similarity(x, y) where every row of x has length d1 and every row of y has length d2 != d1 — classically query embeddings produced by one model and document embeddings by another (different embedding dimensions, e.g. 1536 vs 3072, or 384 vs 768). Also triggered by malformed hand-built 1-D ragged inputs that np.array turns into an object/differently-shaped matrix.
Common situations: Switching embedding providers or model versions (e.g. moving documents from a 384-dim model to a 1536-dim model) without re-embedding the corpus; mixing query embeddings from a new model with a stale vector store embedded by the old one; copy-paste test fixtures with placeholder vectors of the wrong length; loading embeddings saved before a model upgrade.
Related errors
- NaN values found, please remove the NaN values and try again
- cosine_similarity requires numpy to be installed. Please ins
- ids must be the same length as texts. Got {len(ids)} ids and
- numpy must be installed to use max_marginal_relevance_search
- maximal_marginal_relevance requires numpy to be installed. P
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/ab761e31f1493d45.
Report an issue: GitHub.