langchain-ai/langchain · error · ValueError

Received disallowed comparator {func}. Allowed comparators a

Error message

Received disallowed comparator {func}. Allowed comparators are {self.allowed_comparators}

What it means

The comparator half of the structured-query translator validation: a `Comparison` node using a comparator (e.g. `LIKE`, `CONTAINS`, `GT`) that is not in the translator's `allowed_comparators` raises this ValueError during `visit_comparison`. Vector-store translators declare which comparators their search API can express, and anything outside that set is rejected.

Source

Thrown at libs/core/langchain_core/structured_query.py:44

            isinstance(func, Operator)
            and self.allowed_operators is not None
            and func not in self.allowed_operators
        ):
            msg = (
                f"Received disallowed operator {func}. Allowed "
                f"comparators are {self.allowed_operators}"
            )
            raise ValueError(msg)
        if (
            isinstance(func, Comparator)
            and self.allowed_comparators is not None
            and func not in self.allowed_comparators
        ):
            msg = (
                f"Received disallowed comparator {func}. Allowed "
                f"comparators are {self.allowed_comparators}"
            )
            raise ValueError(msg)

    @abstractmethod
    def visit_operation(self, operation: Operation) -> Any:
        """Translate an Operation.

        Args:
            operation: Operation to translate.
        """

    @abstractmethod
    def visit_comparison(self, comparison: Comparison) -> Any:
        """Translate a Comparison.

        Args:
            comparison: Comparison to translate.
        """

    @abstractmethod

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Look up `allowed_comparators` on the store's translator and restrict the self-query prompt or metadata info so the LLM only emits supported comparators.
  2. Rewrite the filter using allowed comparators (e.g. `like` → `contains` if supported, or drop the predicate and post-filter in Python).
  3. For custom translators, add the comparator to `allowed_comparators` and implement its translation in `visit_comparison`.

Example fix

# before
Comparison('like', 'title', '%report%')  # translator lacks Comparator.LIKE
# after
Comparison('eq', 'doc_type', 'report')  # use a comparator the store supports
Defensive patterns

Strategy: validation

Validate before calling

allowed = set(translator.allowed_comparators or [])
comps = collect_comparisons(filter_expr)
unsupported = comps - allowed
if unsupported:
    filter_expr = rewrite_comparisons(filter_expr, allowed)

Type guard

def comparator_allowed(translator, comp) -> bool:
    return translator.allowed_comparators is None or comp in translator.allowed_comparators

Try / catch

try:
    out = translator.visit_comparison(comp_node)
except ValueError as e:
    if 'disallowed comparator' in str(e):
        out = None  # drop predicate, post-filter results in Python instead
    else:
        raise

Prevention

When it happens

Trigger: A self-query retriever's LLM emits a `like`/`between` filter against a vector store whose translator only allows `eq`/`ne`/`lt`/`lte`/`gt`/`gte`; calling `visitor.visit_comparison(Comparison('like', 'title', 'foo'))` on a translator without `LIKE` in `allowed_comparators`.

Common situations: `SelfQueryRetriever` on stores with limited comparator support (the LLM happily generates 'like' because the schema mentions text fields); migrating a filter pipeline between backends with different comparator sets; custom metadata field descriptions inducing unsupported comparisons.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/6f084763be4b7341. Report an issue: GitHub.