dotnet/efcore · error · InvalidOperationException

The same ParameterExpression instance with name '{parameter}

Error message

The same ParameterExpression instance with name '{parameter}' was used as a variable declaration in a block and a nested block inside it. This is not allowed - use different ParameterExpression instances.

What it means

Thrown in VisitBlock (statement context) via DesignStrings.SameParameterExpressionDeclaredAsVariableInNestedBlocks when the same ParameterExpression is declared as a variable in both an outer block and a nested block. InvalidOperationException. This mirrors the System.Linq.Expressions rule that variable ParameterExpressions must be unique within their scope chain. Part of EF Core's LINQ-to-C# syntax translation.

Source

Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:516

        {
            var (variables, variableNames) = (stackFrame.Variables, stackFrame.VariableNames);

            var uniquifiedName = UniquifyVariableName(parameter.Name ?? "unnamed");

            if (blockContext == ExpressionContext.Expression)
            {
                if (!_liftedState.Variables.TryAdd(parameter, uniquifiedName))
                {
                    throw new NotSupportedException("Parameter clash during expression lifting for: " + parameter.Name);
                }

                _liftedState.VariableNames.Add(uniquifiedName);
            }
            else
            {
                if (!variables.TryAdd(parameter, uniquifiedName))
                {
                    throw new InvalidOperationException(
                        DesignStrings.SameParameterExpressionDeclaredAsVariableInNestedBlocks(parameter.Name ?? "<null>"));
                }

                variableNames.Add(uniquifiedName);
            }
        }

        var unassignedVariables = block.Variables.ToList();

        var statements = new List<StatementSyntax>();
        LabeledStatementSyntax? pendingLabeledStatement = null;

        // Now visit the block's expressions
        for (var i = 0; i < block.Expressions.Count; i++)
        {
            var expression = block.Expressions[i];
            var onLastBlockLine = i == block.Expressions.Count - 1;
            _onLastLambdaLine = parentOnLastLambdaLine && onLastBlockLine;

View on GitHub (pinned to dbf9771522)

Solutions

  1. Create separate ParameterExpression instances for the nested block.
  2. If the variable should be shared, declare it only in the outermost block and reference it inside.

Example fix

// before
var v = Expression.Variable(typeof(int));
var inner = Expression.Block(new[] { v }, expr); // re-declared
var outer = Expression.Block(new[] { v }, inner);
// after
var v = Expression.Variable(typeof(int));
var inner = Expression.Block(expr);             // do not redeclare
var outer = Expression.Block(new[] { v }, inner);
Defensive patterns

Strategy: validation

Validate before calling

// Detect a ParameterExpression declared in both an outer and nested block
foreach (var outer in AllBlocks(expr))
{
    var outerVars = new HashSet<ParameterExpression>(outer.Variables);
    foreach (var inner in outer.Expressions.OfType<BlockExpression>())
        foreach (var v in inner.Variables)
            if (outerVars.Contains(v))
                throw new InvalidOperationException(
                    $"ParameterExpression '{v.Name}' is declared in both an outer and nested block.");
}

Prevention

When it happens

Trigger: Constructing a BlockExpression where the same ParameterExpression appears in .Variables of both the outer block and an inner nested block.

Common situations: Manual expression-tree construction reusing a parameter in nested Block variables; this is also invalid per System.Linq.Expressions semantics at runtime.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/e9205a6561979392. Report an issue: GitHub.