MemPalace/mempalace · error · UnsupportedFilterError
operator {k!r} not supported by chroma backend
Error message
operator {k!r} not supported by chroma backend What it means
A MaxSeqIdVerificationError raised at the end of repair_max_seq_id: after applying the repair plan, re-running poisoned-row detection still finds rows above the threshold. The repair wrote changes but verification failed, meaning the fix did not take effect for all planned segments; a backup of the pre-repair state is referenced in the message.
Source
Thrown at mempalace/backends/chroma.py:279
# (don't attempt recovery on segments with negligible data).
_HNSW_MISSING_METADATA_DATA_FLOOR = 1024
def _validate_where(where: Optional[dict]) -> None:
"""Scan a where-clause for unknown operators and raise ``UnsupportedFilterError``.
Spec (RFC 001 §1.4): silent dropping of unknown operators is forbidden.
"""
if not where:
return
stack = [where]
while stack:
node = stack.pop()
if not isinstance(node, dict):
continue
for k, v in node.items():
if k.startswith("$") and k not in _SUPPORTED_OPERATORS:
raise UnsupportedFilterError(f"operator {k!r} not supported by chroma backend")
if isinstance(v, dict):
stack.append(v)
elif isinstance(v, list):
stack.extend(x for x in v if isinstance(x, dict))
def _tokenize(text: str) -> list[str]:
if not text:
return []
return _TOKEN_RE.findall(text.lower())
def _bm25_scores(
query: str,
documents: list[str],
k1: float = 1.5,
b: float = 0.75,
) -> list[float]:View on GitHub (pinned to 06cb6987f0)
Solutions
- Stop all processes that touch the palace's chroma.sqlite3 (MCP server, mining hooks) and re-run the repair.
- Compare the remaining segment ids in the message against result['segment_repaired'] to see which segments were missed.
- If state looks wrong, restore from the backup path named in the message.
- Re-run detection with the same threshold/segment arguments used for the repair to rule out argument drift.
Defensive patterns
Strategy: retry
Validate before calling
from mempalace import repair
poisoned = repair._detect_poisoned_max_seq_ids(db_path, threshold=threshold)
if poisoned:
ensure_no_live_chromadb_processes(palace_path) # lsof/fuser check Try / catch
try:
repair_max_seq_id(palace_path, threshold=threshold)
except MaxSeqIdVerificationError as e:
stop_palace_processes()
repair_max_seq_id(palace_path, threshold=threshold) # retry with DB quiescent Prevention
- Run seq_id repairs only when no chromadb client (MCP server, miner, hooks) is live.
- Use identical threshold/segment arguments across detection and repair passes.
- Keep the automatic backup referenced in the error until verification passes.
When it happens
Trigger: The post-repair _detect_poisoned_max_seq_ids() call still returns rows — e.g. another process rewrote seq_ids between the UPDATE and the check, the plan missed segments, or the detection threshold/context differs between runs.
Common situations: Running the repair while chromadb (MCP server, miner) is live and rewriting the DB; concurrent repairs; a detection threshold passed differently on the retry.
Related errors
- collection was built with a {stored.dimension}-dim embedder
- collection was built with embedder {stored.model_name!r} but
- backend does not support facet_counts
- backend does not support maintenance kind {kind!r}
- backend does not support lexical_search
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/6c7c30a8cdfaa9c9.
Report an issue: GitHub.