MemPalace/mempalace · error · UnsupportedFilterError

operator {op!r} not supported by sqlite_exact

Error message

operator {op!r} not supported by sqlite_exact

What it means

Raised by sqlite_exact's `_compare` helper when it is handed a comparison operator it does not implement. `_compare` handles equality/inequality, containment, `$contains`, and `$gt/$gte/$lt/$lte`; reaching the final `raise` means the operator string fell through every branch. It is a defensive backstop for operators that slipped past `_validate_where`.

Source

Thrown at mempalace/backends/sqlite_exact.py:184

        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 sqlite_exact")


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 sqlite_exact")

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Rewrite the filter using only supported comparison operators ($eq, $ne, $gt, $gte, $lt, $lte, $in, $contains).
  2. If you expect this operator to exist, check `_SUPPORTED_OPERATORS` in your installed version — the allow-list and `_compare` may have drifted; upgrade mempalace.
  3. Report the mismatch as a bug: `_validate_where` should have rejected the operator earlier, so both lists need to agree.

Example fix

# before
where = {"score": {"$between": [1, 5]}}

# after
where = {"$and": [{"score": {"$gte": 1}}, {"score": {"$lte": 5}}]}
Defensive patterns

Strategy: try-catch

Validate before calling

SUPPORTED_COMPARE = {"$eq", "$ne", "$gt", "$gte", "$lt", "$lte", "$in", "$contains"}

def safe_field_filter(field_op: dict) -> dict:
    bad = [op for op in field_op if op.startswith("$") and op not in SUPPORTED_COMPARE]
    if bad:
        raise ValueError(f"unsupported comparison ops {bad}")
    return field_op

Type guard

def is_supported_compare(op: str) -> bool:
    return op in {"$eq", "$ne", "$gt", "$gte", "$lt", "$lte", "$in", "$contains"}

Try / catch

try:
    results = col.get(where=where)
except UnsupportedFilterError:
    results = col.get()  # broad fetch, then post-filter in Python
    results = post_filter(results, where)

Prevention

When it happens

Trigger: A `where` clause like `{"field": {"$between": [1, 5]}}` or any `$op` not in the supported comparison set reaching `_matches_where` -> `_compare`. Because `_validate_where` normally rejects unknown operators first, this typically fires when validation is skipped, the supported-set and compare branches drift out of sync, or a caller invokes the private matcher directly.

Common situations: Version skew between the operator allow-list and `_compare` after a partial upgrade; calling internal `_matches_where`/`_compare` helpers from custom code or tests; filters constructed dynamically from user input without validation.

Related errors


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