langchain-ai/langchain · error · ValueError
search_type of {self.search_type} not allowed.
Error message
search_type of {self.search_type} not allowed. What it means
Defensive dispatch inside `VectorStoreRetriever._get_relevant_documents`: after checking the three known `search_type` values, an unrecognized value falls into the `else` branch and raises `ValueError`. Normally unreachable because the Pydantic validator rejects bad values at construction, but it catches subclasses that loosen validation, mutate `search_type` after construction, or construct the model bypassing validators (`model_construct`).
Source
Thrown at libs/core/langchain_core/vectorstores/base.py:1057
@override
def _get_relevant_documents(
self, query: str, *, run_manager: CallbackManagerForRetrieverRun, **kwargs: Any
) -> list[Document]:
kwargs_ = self.search_kwargs | kwargs
if self.search_type == "similarity":
docs = self.vectorstore.similarity_search(query, **kwargs_)
elif self.search_type == "similarity_score_threshold":
docs_and_similarities = (
self.vectorstore.similarity_search_with_relevance_scores(
query, **kwargs_
)
)
docs = [doc for doc, _ in docs_and_similarities]
elif self.search_type == "mmr":
docs = self.vectorstore.max_marginal_relevance_search(query, **kwargs_)
else:
msg = f"search_type of {self.search_type} not allowed."
raise ValueError(msg)
return docs
@override
async def _aget_relevant_documents(
self,
query: str,
*,
run_manager: AsyncCallbackManagerForRetrieverRun,
**kwargs: Any,
) -> list[Document]:
kwargs_ = self.search_kwargs | kwargs
if self.search_type == "similarity":
docs = await self.vectorstore.asimilarity_search(query, **kwargs_)
elif self.search_type == "similarity_score_threshold":
docs_and_similarities = (
await self.vectorstore.asimilarity_search_with_relevance_scores(
query, **kwargs_
)View on GitHub (pinned to e32fa9a52e)
Solutions
- Set `search_type` at construction time to a validator-approved value instead of mutating it afterwards.
- If you subclass and extend `allowed_search_types`, also override `_get_relevant_documents` (and `_aget_relevant_documents`) to handle the new values.
- Re-validate after mutation: `retriever = VectorStoreRetriever.model_validate(retriever.model_dump())`.
Example fix
# before
retriever = store.as_retriever()
retriever.search_type = "hybrid" # passes attribute set, fails at query time
docs = retriever.invoke("query") # ValueError: search_type of hybrid not allowed
# after
class HybridRetriever(VectorStoreRetriever):
allowed_search_types = VectorStoreRetriever.allowed_search_types | {"hybrid"}
def _get_relevant_documents(self, query, *, run_manager, **kwargs):
if self.search_type == "hybrid":
return self._hybrid_search(query, **kwargs)
return super()._get_relevant_documents(query, run_manager=run_manager, **kwargs) Defensive patterns
Strategy: validation
Validate before calling
from langchain_core.vectorstores import VectorStoreRetriever
def set_search_type(retriever, search_type: str):
"""Safely change search_type by re-validating instead of mutating."""
if search_type not in retriever.allowed_search_types:
raise ValueError(f"{search_type!r} not in {retriever.allowed_search_types}")
return retriever.model_copy(update={"search_type": search_type}) Type guard
def retriever_search_type_is_valid(retriever, value: str) -> bool:
"""Narrow before dispatch; guards post-construction mutation."""
return value in type(retriever).allowed_search_types Try / catch
try:
docs = retriever.invoke(query)
except ValueError as e:
if "search_type" in str(e):
retriever = retriever.model_copy(update={"search_type": "similarity"})
docs = retriever.invoke(query)
else:
raise Prevention
- Never assign `retriever.search_type` directly; rebuild via `as_retriever(...)` or `model_copy(update=...)`.
- Subclasses adding search types must update `allowed_search_types` AND both dispatch methods.
- Add a regression test that constructs your retriever config through normal validation (not `model_construct`).
When it happens
Trigger: Mutating `retriever.search_type = 'custom'` after creation; a subclass overriding the validator or `allowed_search_types` without handling the new value in `_get_relevant_documents`; building the retriever via `model_construct` (no validation) with an invalid type.
Common situations: Dynamic config applied by assigning attributes post-init; custom retriever subclasses adding search modes that pass validation but skip dispatch handling; deserialization paths that skip Pydantic validation.
Related errors
- No runnable associated with key '{key}'
- Tool definition for {name} must include valid type annotatio
- search_type of {search_type} not allowed. Valid values are:
- `score_threshold` is not specified with a float value(0~1) i
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/13c07df43a4ba422.
Report an issue: GitHub.