{"record":{"id":"58c4dca023c7365e","repo":"microsoft/semantic-kernel","slug":"filter-expected-len-lambda-param-order-argument","errorCode":null,"errorMessage":"Filter expected {len(lambda_param_order)} argument(s), but received {len(args)}.","messagePattern":"Filter expected (.+?) argument\\(s\\), but received (.+?)\\.","errorType":"validation","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":845,"sourceCode":"            if (\n                isinstance(node, ast.Constant)\n                and isinstance(node.value, str)\n                and len(node.value) > self.max_filter_literal_collection_size\n            ):\n                raise VectorStoreOperationException(\n                    \"String literals in filter expressions exceed the maximum allowed size.\"\n                )\n\n        evaluator = _SafeFilterEvaluator(\n            direct_call_functions=self.direct_filter_functions,\n            blocked_attributes=self.blocked_filter_attributes,\n            max_literal_collection_size=self.max_filter_literal_collection_size,\n            max_sequence_repeat_size=self.max_filter_sequence_repeat_size,\n        )\n\n        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","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L827-L863","documentation":"Thrown by the filter_callable closure returned from _parse_and_validate_filter (in_memory.py:845) when it is invoked with a number of arguments that does not match the lambda's declared parameter count (lambda_param_order). Internally _run_filter calls the filter with exactly one argument (the wrapped record), so a string lambda declaring more than one parameter will mismatch.","triggerScenarios":"A string filter lambda with multiple parameters, e.g. \"lambda x, y: x.age > y\", passed via VectorSearchOptions.filter. The evaluator only ever supplies the single record, so len(args)=1 != len(lambda_param_order)=2 at in_memory.py:844.","commonSituations":"Writing a two-argument lambda expecting an extra context parameter; copy-pasting a lambda signature from elsewhere; misunderstanding that the filter receives only the record.","solutions":["Use a single-parameter lambda: \"lambda x: x.age > 18\".","Inline any second value as a literal in the expression.","If you genuinely need multi-arg semantics, pass a Python callable and arrange the call site yourself (note _run_filter still passes one record).","Keep string filters to the documented one-parameter shape."],"exampleFix":"# before\nfilter = \"lambda x, threshold: x.age > threshold\"\n\n# after\nfilter = \"lambda x: x.age > 18\"","handlingStrategy":"validation","validationCode":"import ast\n\ndef lambda_param_count(filter_str: str) -> int:\n    tree = ast.parse(filter_str, mode=\"eval\")\n    assert isinstance(tree.body, ast.Lambda)\n    return len(tree.body.args.args)\n\n# the in-memory evaluator only supplies the record, so require exactly 1:\nassert lambda_param_count(filter_str) == 1","typeGuard":"def is_single_param_lambda(filter_str: str) -> bool:\n    try:\n        tree = ast.parse(filter_str, mode=\"eval\")\n    except SyntaxError:\n        return False\n    return (\n        isinstance(tree, ast.Expression)\n        and isinstance(tree.body, ast.Lambda)\n        and len(tree.body.args.args) == 1\n    )","tryCatchPattern":"try:\n    opts = VectorSearchOptions(filter=filter_str)\nexcept VectorStoreOperationException as ex:\n    if \"argument(s), but received\" in str(ex):\n        # rewrite to a single-param lambda with the second value inlined\n        filter_str = filter_str.replace(\"lambda x, y:\", \"lambda x:\").replace(\", y\", \"\")","preventionTips":["Always write string filters as a single-parameter lambda.","Inline any second value as a literal rather than a parameter.","Validate the param count before passing to search.","Remember _run_filter only ever passes the one record."],"tags":["in-memory-collection","filter","arity","lambda"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}