dotnet/efcore · error · ArgumentOutOfRangeException

Unsupported LINQ unary node: {unary.NodeType}

Error message

Unsupported LINQ unary node: {unary.NodeType}

What it means

The switch over unary.NodeType in VisitUnary covers Negate, Not, Convert, Throw, Quote, increment/decrement, array-length, etc. Any other ExpressionType falls through to ArgumentOutOfRangeException("Unsupported LINQ unary node: ..."). It signals a unary node type the translator was never taught to render.

Source

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

            ExpressionType.IsTrue => operand,
            ExpressionType.ArrayLength => _g.MemberAccessExpression(operand, "Length"),
            ExpressionType.Convert => ParenthesizedExpression((ExpressionSyntax)_g.ConvertExpression(Generate(unary.Type), operand)),
            ExpressionType.ConvertChecked =>
                ParenthesizedExpression((ExpressionSyntax)_g.ConvertExpression(Generate(unary.Type), operand)),
            ExpressionType.Throw when unary.Type == typeof(void) => _g.ThrowStatement(operand),
            ExpressionType.Throw => _g.ThrowExpression(operand),
            ExpressionType.TypeAs => BinaryExpression(SyntaxKind.AsExpression, operand, Generate(unary.Type)),
            ExpressionType.Quote => operand,
            ExpressionType.UnaryPlus => PrefixUnaryExpression(SyntaxKind.UnaryPlusExpression, operand),
            ExpressionType.Unbox => operand,
            ExpressionType.Increment => Translate(Expression.Add(unary.Operand, Expression.Constant(1))),
            ExpressionType.Decrement => Translate(Expression.Subtract(unary.Operand, Expression.Constant(1))),
            ExpressionType.PostIncrementAssign => PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, operand),
            ExpressionType.PostDecrementAssign => PostfixUnaryExpression(SyntaxKind.PostDecrementExpression, operand),
            ExpressionType.PreIncrementAssign => PrefixUnaryExpression(SyntaxKind.PreIncrementExpression, operand),
            ExpressionType.PreDecrementAssign => PrefixUnaryExpression(SyntaxKind.PreDecrementExpression, operand),

            _ => throw new ArgumentOutOfRangeException("Unsupported LINQ unary node: " + unary.NodeType)
        };

        return unary;
    }

    /// <inheritdoc />
    protected override Expression VisitMemberInit(MemberInitExpression memberInit)
    {
        var objectCreation = Translate<ObjectCreationExpressionSyntax>(memberInit.NewExpression);

        List<MemberListBinding>? incompatibleListBindings = null;

        var initializerExpressions = new List<AssignmentExpressionSyntax>(memberInit.Bindings.Count);

        foreach (var binding in memberInit.Bindings)
        {
            // C# collection initialization syntax only works when Add is called on an IEnumerable, but LINQ supports arbitrary add
            // methods. Skip these, we'll add them later outside the initializer

View on GitHub (pinned to dbf9771522)

Solutions

  1. Identify the NodeType in the message and rewrite it using supported primitives (e.g. expand a custom unary into arithmetic).
  2. Avoid unsupported unary operators in precompiled query expressions.
  3. Report to EF Core if the node type is common and legitimately needed.

Example fix

// before
var u = Expression.MakeUnary(obscureNodeType, operand, typeof(int));
// after
var u = Expression.Add(operand, Expression.Constant(1)); // express with supported nodes
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the NodeType is in the supported set before translating
static readonly HashSet<ExpressionType> Supported = new() {
    ExpressionType.Negate, ExpressionType.NegateChecked, ExpressionType.Not,
    ExpressionType.OnesComplement, ExpressionType.IsFalse, ExpressionType.IsTrue,
    ExpressionType.ArrayLength, ExpressionType.Convert, ExpressionType.ConvertChecked,
    ExpressionType.Throw, ExpressionType.TypeAs, ExpressionType.Quote, ExpressionType.UnaryPlus,
    ExpressionType.Unbox, ExpressionType.Increment, ExpressionType.Decrement,
    ExpressionType.PostIncrementAssign, ExpressionType.PostDecrementAssign,
    ExpressionType.PreIncrementAssign, ExpressionType.PreDecrementAssign };
bool ok = Supported.Contains(unary.NodeType);

Type guard

static bool IsSupportedUnary(ExpressionType t) => Supported.Contains(t);

Try / catch

try { translator.Translate(lambda); }
catch (ArgumentOutOfRangeException ex) when (ex.Message.Contains("Unsupported LINQ unary node")) {
    // rewrite the offending unary using supported primitives
}

Prevention

When it happens

Trigger: A UnaryExpression whose NodeType is outside the handled set — an uncommon or newer LINQ node type reaching the translator.

Common situations: Expression rewriting that introduces unusual unary node types; rarely produced by ordinary user code.

Related errors


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