microsoft/semantic-kernel · error · VectorStoreOperationException

Method '{node.func.attr}' is not available in filter express

Error message

Method '{node.func.attr}' is not available in filter expressions.

What it means

For method calls (ast.Attribute func) other than contains, _eval_Call resolves the method via getattr(target, node.func.attr). If the target value has no such attribute, AttributeError is caught and re-raised as VectorStoreOperationException. The method name already passed the static allowed_filter_functions check, so this fires when the field's runtime type does not provide that method.

Source

Thrown at python/semantic_kernel/connectors/in_memory.py:297

            try:
                func = self._direct_call_functions[node.func.id]
            except KeyError as e:
                raise VectorStoreOperationException(
                    f"Function '{node.func.id}' is only supported as a method call in filter expressions."
                ) from e
            return func(*args)

        if isinstance(node.func, ast.Attribute):
            target = self.evaluate(node.func.value, context)
            if node.func.attr == "contains":
                if len(args) != 1:
                    raise VectorStoreOperationException("Method 'contains' expects exactly one argument.")
                return args[0] in target

            try:
                func = getattr(target, node.func.attr)
            except AttributeError as e:
                raise VectorStoreOperationException(
                    f"Method '{node.func.attr}' is not available in filter expressions."
                ) from e

            if not callable(func):
                raise VectorStoreOperationException(
                    f"Attribute '{node.func.attr}' is not callable in filter expressions."
                )
            return func(*args)

        raise VectorStoreOperationException(
            f"Call target node type '{type(node.func).__name__}' is not allowed in filter expressions."
        )

    def _compare(self, operator_node: ast.AST, left: Any, right: Any) -> bool:
        """Evaluate a comparison operator."""
        if isinstance(operator_node, ast.Eq):
            return left == right
        if isinstance(operator_node, ast.NotEq):

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure the field is the expected type before calling type-specific methods on it.
  2. Coerce explicitly with an allowed builtin: lambda x: str(x.count).startswith('a').
  3. Guard for None: lambda x: x.count is not None and str(x.count).startswith('a').

Example fix

# before
VectorSearchOptions(filter=lambda x: x.count.startswith('a'))  # count is int -> [1319]

# after
VectorSearchOptions(filter=lambda x: str(x.count).startswith('a'))
Defensive patterns

Strategy: type-guard

Validate before calling

def coerce_before_method_call(filter_str: str, field_types: dict[str, type]) -> str:
    # ensure string methods are called on str-typed fields, e.g. wrap with str()
    for field, typ in field_types.items():
        if typ is not str and any(m in filter_str for m in ('.startswith', '.endswith', '.upper', '.lower', '.strip')):
            filter_str = filter_str.replace(f'{field}.', f'str({field}).')
    return filter_str

Type guard

def field_supports_method(value, method: str) -> bool:
    return callable(getattr(value, method, None))

Try / catch

from semantic_kernel.exceptions import VectorStoreOperationException
try:
    await collection.search(vector=[...], options=opts)
except VectorStoreOperationException as ex:
    if 'is not available in filter expressions' in str(ex):
        # coerce the field to the expected type, e.g. str(x.count).startswith('a')
        opts.filter = "lambda x: str(x.count).startswith('a')"
        await collection.search(vector=[...], options=opts)
    else:
        raise

Prevention

When it happens

Trigger: Calling a string method on a non-string field, e.g. lambda x: x.count.startswith('a') where count is an int, or lambda x: x.tags.upper() where tags is a list. The method name is allowed but the value lacks it.

Common situations: Field type mismatch between the data model and the actual stored value; optional fields returning None; schema drift; assuming a field is a string when it is a number/list.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/6738853640e18b4c. Report an issue: GitHub.