{"record":{"id":"b1b0480fabdf3124","repo":"MemPalace/mempalace","slug":"operator-op-r-not-supported-by-qdrant","errorCode":null,"errorMessage":"operator {op!r} not supported by qdrant","messagePattern":"operator (.+?) not supported by qdrant","errorType":"exception","errorClass":"UnsupportedFilterError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/qdrant.py","lineNumber":169,"sourceCode":"        return actual != expected\n    if op == \"$in\":\n        return actual in (expected or [])\n    if op == \"$nin\":\n        return actual not in (expected or [])\n    if op == \"$contains\":\n        return str(expected) in str(actual or \"\")\n    try:\n        if op == \"$gt\":\n            return actual > expected\n        if op == \"$gte\":\n            return actual >= expected\n        if op == \"$lt\":\n            return actual < expected\n        if op == \"$lte\":\n            return actual <= expected\n    except TypeError:\n        return False\n    raise UnsupportedFilterError(f\"operator {op!r} not supported by qdrant\")\n\n\ndef _matches_where(meta: dict, where: Optional[dict]) -> bool:\n    if not where:\n        return True\n    if not isinstance(where, dict):\n        return False\n    for key, expected in where.items():\n        if key == \"$and\":\n            if not all(_matches_where(meta, clause) for clause in expected or []):\n                return False\n            continue\n        if key == \"$or\":\n            if not any(_matches_where(meta, clause) for clause in expected or []):\n                return False\n            continue\n        if key.startswith(\"$\"):\n            raise UnsupportedFilterError(f\"operator {key!r} not supported by qdrant\")","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/qdrant.py#L151-L187","documentation":"_compare implements the local-filter fallback ($gt, $gte, $lt, $lte and equality/contains semantics). If it is ever called with an operator outside that set it raises UnsupportedFilterError as a defensive assertion — normally unreachable because _validate_where rejects unknown operators first. Hitting it means an operator slipped past validation (e.g. a newly added comparator or an operator reachable only through _matches_where paths).","triggerScenarios":"Calling _compare(meta_value, \"$regex\", \"x\") directly, or a filter operator that exists in _SUPPORTED_OPERATORS but has no branch in _compare.","commonSituations":"Extending _SUPPORTED_OPERATORS without adding a _compare branch; library upgrades that add pushdown operators without local-comparison counterparts.","solutions":["If you maintain the library: add a matching branch in _compare for any operator you add to _SUPPORTED_OPERATORS (and a test).","As a caller: stick to the documented operator set and rewrite exotic filters.","Report the specific operator that triggered it — this path indicates an internal inconsistency."],"exampleFix":"# before\n# _SUPPORTED_OPERATORS extended with \"$ne\" but _compare has no branch:\n_matches_where(meta, {\"status\": {\"$ne\": \"archived\"}})\n\n# after\n# add to _compare:\n#   if op == \"$ne\":\n#       return actual != expected","handlingStrategy":"validation","validationCode":"# callers: pre-restrict operators to the set _compare implements\nALLOWED_COMPARE = {\"$eq\", \"$gt\", \"$gte\", \"$lt\", \"$lte\"}\ndef safe_compare(actual, op, expected):\n    if op not in ALLOWED_COMPARE:\n        raise ValueError(f\"unsupported comparator {op}\")\n    return _compare(actual, op, expected)","typeGuard":"def is_comparable_op(op: str) -> bool:\n    return op in {\"$eq\", \"$gt\", \"$gte\", \"$lt\", \"$lte\"}","tryCatchPattern":"try:\n    _compare(actual, op, expected)\nexcept UnsupportedFilterError:\n    logger.exception(\"internal filter mismatch: operator %r lacks a compare branch\", op)\n    raise","preventionTips":["If you fork/extend the backend, add a _compare branch and a test for every operator you whitelist.","Run the backend's own filter test suite after touching _SUPPORTED_OPERATORS."],"tags":["qdrant","filters","internal-invariant","unsupported-operation"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}