RyanCodrai/turbovec · error · TypeError

filter must be a dict of metadata key/value pairs or a calla

Error message

filter must be a dict of metadata key/value pairs or a callable taking a Document, got {type(filter).__name__}

What it means

TypeError raised in _compile_filter (used by _search_vector) when the filter is neither a dict of metadata key/value pairs nor a callable taking a Document — e.g. a string or list. Only these two forms are compiled into the predicate applied to each candidate document.

Source

Thrown at turbovec-python/python/turbovec/langchain.py:681

        if isinstance(filter, dict):
            items = list(filter.items())
            # Key presence is required (#381). `dict.get` returns None both
            # for "absent" and for "present and None", so the old
            # `doc.metadata.get(k) == v` form let a document with no `k` at
            # all satisfy `filter={"k": None}`. The reference
            # InMemoryVectorStore accepts *only* callables, so nothing
            # upstream fixes the dict form's meaning — but the dict form is
            # sugar for the callable a user would otherwise write, and
            # nobody writes `lambda d: d.metadata.get("k") is None` meaning
            # "documents without k". Matching an absent key also can't be
            # asked for any other way, whereas "has k, and it's None" can't
            # be expressed at all under the loose form. This is the same
            # leak Agno's `_meta_matches` fixed in #144; the two dict
            # filters now agree.
            return lambda doc: all(
                k in doc.metadata and doc.metadata[k] == v for k, v in items
            )
        raise TypeError(
            "filter must be a dict of metadata key/value pairs or a callable "
            f"taking a Document, got {type(filter).__name__}"
        )

    # ---- Max marginal relevance ---------------------------------------
    #
    # MMR requires the full-precision vector of every candidate to compute
    # pairwise diversity scores. turbovec discards full vectors after
    # quantization (that's the point), so we can't faithfully implement
    # MMR. Raise loudly with a useful message rather than silently fall
    # back to the base class's bare NotImplementedError.

    _MMR_MSG = (
        "TurboQuantVectorStore does not support max-marginal-relevance "
        "search because the underlying quantized index discards "
        "full-precision vectors after compression. MMR requires the "
        "original embedding for every candidate to compute pairwise "
        "diversity. Use `similarity_search` / `similarity_search_with_score` "

View on GitHub (pinned to ccab9f325e)

Solutions

  1. Pass a dict like {'source': 'web'} or a predicate lambda doc: doc.metadata['k'] == v.
  2. Wrap richer filter expressions into a callable taking the Document.
  3. Catch the TypeError in search code to reject malformed filters with a clear message.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at turbovec-python/python/turbovec/langchain.py:681 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06). Data as JSON: /api/errors/c0a56c56e0ac5dba. Report an issue: GitHub.