MemPalace/mempalace · error · UnsupportedFilterError

operator {op!r} not supported by chroma backend

Error message

operator {op!r} not supported by chroma backend

What it means

A ValueError from replica identity loading: the palace's replica file exists but cannot be parsed as JSON or lacks the replica_id key. The code refuses to mint a second identity because two replica ids for one palace would fork its op-log provenance — the caller must restore or delete the corrupt file explicitly.

Source

Thrown at mempalace/backends/chroma.py:366

        return actual != expected
    if op == "$in":
        return actual in (expected or [])
    if op == "$nin":
        return actual not in (expected or [])
    if op == "$contains":
        return str(expected) in str(actual or "")
    try:
        if op == "$gt":
            return actual > expected
        if op == "$gte":
            return actual >= expected
        if op == "$lt":
            return actual < expected
        if op == "$lte":
            return actual <= expected
    except TypeError:
        return False
    raise UnsupportedFilterError(f"operator {op!r} not supported by chroma backend")


def _matches_where(meta: dict, where: Optional[dict]) -> bool:
    if not where:
        return True
    if not isinstance(where, dict):
        return False
    for key, expected in where.items():
        if key == "$and":
            if not all(_matches_where(meta, clause) for clause in expected or []):
                return False
            continue
        if key == "$or":
            if not any(_matches_where(meta, clause) for clause in expected or []):
                return False
            continue
        if key.startswith("$"):
            raise UnsupportedFilterError(f"operator {key!r} not supported by chroma backend")

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Inspect the file at the printed path — if it is truncated/garbled, restore it from a backup of the palace.
  2. If you intentionally want a NEW identity (accepting that this replica's provenance history is abandoned), delete the file explicitly and let the tool re-mint.
  3. Never hand-edit a replacement JSON in place unless it is valid {"replica_id": "..."} with the original id.

Example fix

path = Path(palace_path) / 'replica.json'
try:
    rid = load_or_mint_replica_id(palace_path)
except ValueError:
    # decide deliberately: restore old identity from backup, or
    # os.remove(path) to intentionally mint a fresh one
Defensive patterns

Strategy: try-catch

Validate before calling

import json
from pathlib import Path
p = Path(palace_path) / 'replica.json'
if p.exists():
    json.loads(p.read_text(encoding='utf-8'))['replica_id']  # fail early, clearly

Type guard

def is_valid_replica_file(palace_path: str) -> bool:
    p = Path(palace_path) / 'replica.json'
    if not p.is_file():
        return True  # absent is fine; will be minted
    try:
        return isinstance(json.loads(p.read_text())['replica_id'], str)
    except (ValueError, KeyError, TypeError):
        return False

Try / catch

try:
    rid = load_or_mint_replica_id(palace_path)
except ValueError as e:
    if backup_available():
        restore_replica_json_from_backup()
    else:
        raise SystemExit(f'replica identity unreadable: {e}; delete {path} to re-mint')

Prevention

When it happens

Trigger: load_or_mint_replica_id() finds the replica file but json.loads or the data['replica_id'] access raises (ValueError/KeyError/TypeError) — truncated write, hand-edited file, or wrong file dropped in place.

Common situations: A crash or disk-full event truncated the JSON; a sync tool merged the file badly; the user created the file manually with wrong structure.

Related errors


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