{"record":{"id":"bffc27b1d50066bb","repo":"microsoft/semantic-kernel","slug":"dictionary-unpacking-is-not-allowed-in-filter-expr","errorCode":null,"errorMessage":"Dictionary unpacking is not allowed in filter expressions.","messagePattern":"Dictionary unpacking is not allowed in filter expressions\\.","errorType":"exception","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":209,"sourceCode":"        return [self.evaluate(element, context) for element in node.elts]\n\n    def _eval_Tuple(self, node: ast.Tuple, context: Mapping[str, Any]) -> tuple[Any, ...]:\n        \"\"\"Evaluate a tuple literal.\"\"\"\n        self._ensure_literal_collection_size(len(node.elts))\n        return tuple(self.evaluate(element, context) for element in node.elts)\n\n    def _eval_Set(self, node: ast.Set, context: Mapping[str, Any]) -> set[Any]:\n        \"\"\"Evaluate a set literal.\"\"\"\n        self._ensure_literal_collection_size(len(node.elts))\n        return {self.evaluate(element, context) for element in node.elts}\n\n    def _eval_Dict(self, node: ast.Dict, context: Mapping[str, Any]) -> dict[Any, Any]:\n        \"\"\"Evaluate a dict literal.\"\"\"\n        self._ensure_literal_collection_size(len(node.keys))\n        result: dict[Any, Any] = {}\n        for key, value in zip(node.keys, node.values, strict=True):\n            if key is None:\n                raise VectorStoreOperationException(\"Dictionary unpacking is not allowed in filter expressions.\")\n            result[self.evaluate(key, context)] = self.evaluate(value, context)\n        return result\n\n    def _eval_BoolOp(self, node: ast.BoolOp, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate boolean operators with Python short-circuit semantics.\"\"\"\n        if isinstance(node.op, ast.And):\n            result = self.evaluate(node.values[0], context)\n            for value in node.values[1:]:\n                if not result:\n                    return result\n                result = self.evaluate(value, context)\n            return result\n        if isinstance(node.op, ast.Or):\n            result = self.evaluate(node.values[0], context)\n            for value in node.values[1:]:\n                if result:\n                    return result\n                result = self.evaluate(value, context)","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L191-L227","documentation":"_eval_Dict iterates key/value pairs; a dict-unpacking entry (the {**other} form) has a None key in the AST, which the evaluator rejects because unpacking can pull arbitrary, unvalidated objects into the filter. Raises VectorStoreOperationException.","triggerScenarios":"A string filter containing a dict literal with unpacking, e.g. lambda x: {'a': 1, **x.meta}[...]. Note this only reaches the evaluator if dict literals are allowed and the static checks did not reject it.","commonSituations":"Attempting to build complex dicts inside a filter; copying Python dict idioms into filter expressions; adversarial filter input.","solutions":["Do not use ** unpacking inside filter expressions; use explicit key/value literals only.","Restructure the filter to avoid constructing dicts, or precompute the dict outside the filter."],"exampleFix":"# before\nVectorSearchOptions(filter=lambda x: {'k': 1, **x.extra}['k'] == 1)  # -> [1313]\n\n# after\nVectorSearchOptions(filter=lambda x: x.get('k') == 1)","handlingStrategy":"validation","validationCode":"import ast\n\ndef has_no_dict_unpacking(filter_str: str) -> None:\n    for node in ast.walk(ast.parse(filter_str, mode='eval')):\n        if isinstance(node, ast.Dict) and any(k is None for k in node.keys):\n            raise ValueError('dict unpacking (**...) is not allowed in filters')","typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions import VectorStoreOperationException\ntry:\n    await collection.search(vector=[...], options=opts)\nexcept VectorStoreOperationException as ex:\n    if 'Dictionary unpacking' in str(ex):\n        # rewrite the filter without {**...}\n        ...\n    raise","preventionTips":["Do not use ** unpacking inside filter expressions.","Precompute any dict outside the filter."],"tags":["in-memory","filter","ast","security"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}