MemPalace/mempalace · error · UnsupportedFilterError

where_document operator {key!r} not supported

Error message

where_document operator {key!r} not supported

What it means

Raised in translate_where_document() for any key other than $contains, $and, or $or. The document filter subset is deliberately tiny — Milvus can only do substring ('like') matching on the document field — so operators like $eq, $regex, or $not on where_document are rejected with UnsupportedFilterError. Field-level rich operators belong in the metadata where clause, not where_document.

Source

Thrown at mempalace/backends/milvus.py:203

        elif key == "$and":
            if not isinstance(value, list) or not value:
                raise UnsupportedFilterError("$and requires a non-empty list of clauses")
            nested = [translate_where_document(item) for item in value]
            parts.append("(" + " and ".join(part for part in nested if part) + ")")
        elif key == "$or":
            if not isinstance(value, list) or not value:
                raise UnsupportedFilterError("$or requires a non-empty list of clauses")
            nested = [translate_where_document(item) for item in value]
            parts.append("(" + " or ".join(part for part in nested if part) + ")")
        else:
            raise UnsupportedFilterError(f"where_document operator {key!r} not supported")
    return " and ".join(part for part in parts if part)


def _combine_filter(*filters: str) -> str:
    present = [flt for flt in filters if flt]
    if not present:
        return ""
    if len(present) == 1:
        return present[0]
    return "(" + ") and (".join(present) + ")"


def _as_vector_array(vector: list[float]) -> np.ndarray:
    arr = np.asarray(vector, dtype=np.float32)
    if arr.ndim != 1 or arr.size == 0:
        raise ValueError("embedding must be a non-empty 1D vector")
    return arr


def _normalize_vectors(embeddings: list[list[float]]) -> tuple[list[list[float]], int]:
    vectors = []
    dims = set()
    for embedding in embeddings:
        arr = _as_vector_array(embedding)
        vectors.append(arr.astype(float).tolist())

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Use $contains for substring matching on documents
  2. Move equality/range conditions to metadata fields in the where clause (ingest the attribute as metadata if needed)
  3. Post-filter results client-side for regex/negation needs

Example fix

// before
where_document={"$regex": "palace"}

// after
where_document={"$contains": "palace"}
Defensive patterns

Strategy: validation

Validate before calling

DOC_OPS = {"$contains", "$and", "$or"}

def uses_supported_doc_operators(wd: dict) -> bool:
    return all(k in DOC_OPS for k in wd)

Try / catch

from mempalace.backends.base import UnsupportedFilterError
try:
    collection.query(query_texts=[q], where_document=wd, n_results=k)
except UnsupportedFilterError as e:
    if "where_document operator" in str(e):
        raise ValueError("only $contains/$and/$or work on documents; use metadata where for the rest") from e
    raise

Prevention

When it happens

Trigger: where_document={"$regex": "^palace"}, where_document={"$eq": "palace"}, or where_document={"$not": {"$contains": "x"}}.

Common situations: Porting ChromaDB/Mongo document filters verbatim; trying exact-match or negation on document text, which Milvus 'like' cannot express.

Related errors


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/cb7b323a44e0afcf. Report an issue: GitHub.