{"record":{"id":"6373441ac6ee2c8d","repo":"microsoft/semantic-kernel","slug":"error-running-filter-e","errorCode":null,"errorMessage":"Error running filter: {e}","messagePattern":"Error running filter: (.+?)","errorType":"exception","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":861,"sourceCode":"        def filter_callable(*args: Any) -> Any:\n            if len(args) != len(lambda_param_order):\n                raise VectorStoreOperationException(\n                    f\"Filter expected {len(lambda_param_order)} argument(s), but received {len(args)}.\"\n                )\n            context = {\n                name: ReadOnlyAttributeDict._wrap_value(value)\n                for name, value in zip(lambda_param_order, args, strict=True)\n            }\n            return evaluator.evaluate(lambda_node.body, context)\n\n        return filter_callable\n\n    def _run_filter(self, filter: Callable, record: AttributeDict[TAKey, TAValue]) -> bool:\n        \"\"\"Run the filter on the record, supporting attribute access.\"\"\"\n        try:\n            return filter(ReadOnlyAttributeDict(record))\n        except Exception as e:\n            raise VectorStoreOperationException(f\"Error running filter: {e}\") from e\n\n    @override\n    def _lambda_parser(self, node: ast.AST) -> Any:\n        \"\"\"Not used by InMemoryCollection, but required by the interface.\"\"\"\n        pass\n\n    def _calculate_vector_similarity(\n        self,\n        search_vector: Sequence[float | int],\n        record_vector: Sequence[float | int],\n        distance_func: Callable,\n        invert_score: bool = False,\n    ) -> float:\n        calc = distance_func(record_vector, search_vector)\n        if invert_score:\n            return 1.0 - float(calc)\n        return float(calc)\n","sourceCodeStart":843,"sourceCodeEnd":879,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L843-L879","documentation":"Thrown by InMemoryCollection._run_filter (in_memory.py:861), wrapping any exception raised while executing a validated filter callable against a record. The original exception is chained (from e). This indicates the filter passed validation but failed at evaluation time, almost always due to record shape mismatch.","triggerScenarios":"The filter accesses a field that does not exist on a record (AttributeError/KeyError), applies an operator to incompatible types (TypeError), or calls an allowed function with bad arguments. Example: \"lambda x: x.age > 18\" evaluated against a record with no 'age' key.","commonSituations":"Heterogeneous records where some lack the filtered field; schema drift between filter and data; numeric vs string comparison; None values in a comparison; renamed fields.","solutions":["Guard attribute access in the filter: \"lambda x: getattr(x, 'age', None) is not None and x.age > 18\" (getattr is not in the allowlist, so use a callable filter or ensure the field exists).","Normalize records so the filtered field always exists with a consistent type before search.","Catch VectorStoreOperationException and inspect the chained __cause__ to see the underlying AttributeError/TypeError.","Validate the record schema against the filter expression in a dry-run before issuing the search."],"exampleFix":"# before\nfilter = \"lambda x: x.age > 18\"  # fails on records missing 'age'\n\n# after (callable with safe access)\nfilter = lambda r: r.get('age') is not None and r['age'] > 18","handlingStrategy":"try-catch","validationCode":"# dry-run the filter against a sample record before searching\ndef filter_dry_runs(filter_str: str, sample_record: dict) -> bool:\n    from semantic_kernel.connectors.in_memory import InMemoryCollection\n    # parse using the same validator, then evaluate on the sample\n    coll = InMemoryCollection(...)\n    fn = coll._parse_and_validate_filter(filter_str)\n    try:\n        return coll._run_filter(fn, sample_record)\n    except Exception:\n        return False","typeGuard":"def record_has_fields(record: dict, fields: list[str]) -> bool:\n    return all(f in record and record[f] is not None for f in fields)","tryCatchPattern":"from semantic_kernel.exceptions.vector_store_exceptions import VectorStoreOperationException\n\ntry:\n    results = await collection.search(options)\nexcept VectorStoreOperationException as ex:\n    cause = ex.__cause__\n    # cause is usually AttributeError/KeyError/TypeError from record-shape mismatch\n    if isinstance(cause, (KeyError, AttributeError)):\n        options = VectorSearchOptions(filter=lambda x: x.get('age') is not None and x['age'] > 18)","preventionTips":["Ensure all records expose the filtered field with a consistent type before search.","Prefer callable filters that guard missing fields with .get() and None checks.","Run a dry-run of the filter on one sample record during development.","Inspect the chained __cause__ to diagnose the real evaluation error."],"tags":["in-memory-collection","filter","runtime","record-shape","error-wrapping"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}