MemPalace/mempalace · error · UnsupportedFilterError
where_document must be a dict
Error message
where_document must be a dict
What it means
Raised by translate_where_document() when where_document is truthy but not a dict. The document filter only supports a small object shape ($contains, $and, $or), so passing a string, list, or other type fails with UnsupportedFilterError before translation. Falsy values (None, {}, "") are fine and produce an empty filter.
Source
Thrown at mempalace/backends/milvus.py:180
raise UnsupportedFilterError(f"operator {key!r} not supported by milvus")
else:
parts.append(_translate_field(key, value))
return " and ".join(part for part in parts if part)
def translate_where(where: Optional[dict]) -> str:
"""Translate the portable metadata where DSL into a Milvus filter string."""
if not where:
return ""
return _translate_clause(where)
def translate_where_document(where_document: Optional[dict]) -> str:
"""Translate the portable document filter subset into a Milvus filter."""
if not where_document:
return ""
if not isinstance(where_document, dict):
raise UnsupportedFilterError("where_document must be a dict")
parts = []
for key, value in where_document.items():
if key == "$contains":
parts.append(f"{FIELD_DOCUMENT} like {_like_value(value)}")
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)
View on GitHub (pinned to 06cb6987f0)
Solutions
- Always pass the object form: where_document={"$contains": "palace"}
- Add a wrapper that converts a bare string s to {"$contains": s}
- Validate JSON-decoded where_document payloads with isinstance checks before querying
Example fix
// before
results = collection.query(query_texts=[q], where_document="palace")
// after
results = collection.query(query_texts=[q], where_document={"$contains": "palace"}) Defensive patterns
Strategy: type-guard
Validate before calling
def normalize_where_document(wd):
if not wd:
return None
if isinstance(wd, str):
return {"$contains": wd}
if not isinstance(wd, dict):
raise TypeError(f"where_document must be a dict, got {type(wd).__name__}")
return wd Type guard
def is_where_document_dict(wd) -> bool:
return wd is None or wd == {} or isinstance(wd, dict) 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 must be a dict" in str(e):
wd = {"$contains": str(wd)}
return collection.query(query_texts=[q], where_document=wd, n_results=k)
raise Prevention
- Always wrap substrings: {"$contains": s}
- Add a string-shorthand adapter at your API boundary
- Validate user-supplied where_document JSON schemas
When it happens
Trigger: where_document="$contains palace" (operator string instead of dict), where_document=["palace"], or a JSON-parsed value that is a list at the top level.
Common situations: Copy-pasting the substring directly instead of the {$contains: ...} wrapper; wrappers that accept shorthand strings; porting ChromaDB examples incorrectly.
Related errors
- where clause must be a dict, got {type(clause).__name__}
- where_document operator {key!r} not supported
- Milvus filters do not support null comparisons
- Milvus filter field {name!r} is not a safe identifier
- $in requires a non-empty list for {field!r}
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/693956172f30f7bc.
Report an issue: GitHub.