microsoft/semantic-kernel · error · ArgumentException

Expression must be a property access expression

Error message

Expression must be a property access expression

What it means

Thrown by ProcessAgentBuilder.ExtractPropertyInfo when the lambda passed to WithUserStateInput is not a chain of property accesses ending at the lambda parameter (e.g., s => s.SomeProperty.NestedProperty). The method walks the expression tree via MemberExpression nodes; if the terminal node is not a ParameterExpression, the expression is rejected as invalid.

Source

Thrown at dotnet/src/Experimental/Process.Core/ProcessAgentBuilder.cs:206

            propertyPath.Insert(0, member.Name);

            // If this is our first iteration, save the property type
            if (propertyType == null)
            {
                propertyType = ((PropertyInfo)member).PropertyType;
            }

            // Move to the next level in the expression
            expression = memberExpression.Expression;
        }

        if (expression is ParameterExpression)
        {
            // We've reached the parameter (e.g., 'myState'), which is good
            return (propertyName, propertyPath.ToString(), propertyType ?? typeof(TProperty));
        }

        throw new ArgumentException("Expression must be a property access expression", nameof(propertySelector));
    }

    #endregion

    internal override KernelProcessStepInfo BuildStep(ProcessBuilder processBuilder, KernelProcessStepStateMetadata? stateMetadata = null)
    {
        KernelProcessMapStateMetadata? mapMetadata = stateMetadata as KernelProcessMapStateMetadata;

        // Build the edges first
        var builtEdges = this.Edges.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Select(e => e.Build()).ToList());
        var agentActions = new ProcessAgentActions(
            codeActions: new ProcessAgentCodeActions
            {
                OnComplete = this.OnCompleteCodeAction,
                OnError = this.OnCompleteCodeAction
            },
            declarativeActions: new ProcessAgentDeclarativeActions
            {

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure the lambda is a pure property-access chain from the state parameter, e.g., s => s.MyProperty or s => s.Nested.Property.
  2. Replace method calls and computed values with direct property accessors on the state type.
  3. Convert any fields used in the state type to properties (with get/set).

Example fix

// before
builder.WithUserStateInput(s => s.CalculateScore()); // method call — throws

// after
builder.WithUserStateInput(s => s.Score); // direct property access
Defensive patterns

Strategy: validation

Validate before calling

// Validate the expression is a property-access chain before calling WithUserStateInput.
public static bool IsValidPropertyExpression<TState, TProperty>(Expression<Func<TState, TProperty>> expr)
{
    var body = expr.Body;
    while (body is MemberExpression me)
    {
        body = me.Expression;
    }
    return body is ParameterExpression;
}

Type guard

public static bool IsPropertyAccessExpression<TState, TProperty>(Expression<Func<TState, TProperty>> expr)
{
    var node = expr.Body;
    while (node is MemberExpression me)
    {
        node = me.Expression;
        if (me.Member is not PropertyInfo) return false;
    }
    return node is ParameterExpression;
}

Prevention

When it happens

Trigger: Calling WithUserStateInput with a lambda that accesses a method call, a constant, a field (not a property), or a closure variable instead of a direct property chain on the state object. For example: s => s.ComputeValue() or s => _externalValue would both fail.

Common situations: Passing a computed expression or method invocation to WithUserStateInput instead of a simple property accessor. Using a field instead of a property in the state type. Capturing an external variable in the lambda closure rather than referencing the state parameter directly.

Related errors


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