dotnet/efcore · error · InvalidOperationException
Encountered {SyntaxKind.AsExpression} with non-constant type
Error message
Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right} What it means
In the `SyntaxKind.AsExpression` arm of `VisitBinaryExpression`, the translator needs the right operand to be a `ConstantExpression` holding a `Type` (plain `x as SomeType`). Any non-constant right side throws `InvalidOperationException`; only the simple cast-or-null form is translatable.
Source
Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:320
SyntaxKind.BitwiseOrExpression => Or(left, right),
SyntaxKind.BitwiseAndExpression => And(left, right),
SyntaxKind.ExclusiveOrExpression => ExclusiveOr(left, right),
SyntaxKind.EqualsExpression => Equal(left, right),
SyntaxKind.NotEqualsExpression => NotEqual(left, right),
SyntaxKind.LessThanExpression => LessThan(left, right),
SyntaxKind.LessThanOrEqualExpression => LessThanOrEqual(left, right),
SyntaxKind.GreaterThanExpression => GreaterThan(left, right),
SyntaxKind.GreaterThanOrEqualExpression => GreaterThanOrEqual(left, right),
SyntaxKind.IsExpression => TypeIs(
left, right is ConstantExpression { Value: Type type }
? type
: throw new InvalidOperationException(
$"Encountered {SyntaxKind.IsExpression} with non-constant type right argument: {right}")),
SyntaxKind.AsExpression => TypeAs(
left, right is ConstantExpression { Value: Type type }
? type
: throw new InvalidOperationException(
$"Encountered {SyntaxKind.AsExpression} with non-constant type right argument: {right}")),
SyntaxKind.CoalesceExpression => Coalesce(left, right),
_ => throw new ArgumentOutOfRangeException($"BinaryExpressionSyntax with {binary.Kind()}")
};
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override Expression VisitCastExpression(CastExpressionSyntax cast)
=> Convert(Visit(cast.Expression), ResolveType(cast.Type));
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject toView on GitHub (pinned to dbf9771522)
Solutions
- Keep the `as` expression as a plain type conversion (`x as TargetType`).
- If the right side is dynamic, hoist it out of the query.
Example fix
// before var q = ctx.Items.Where(i => (i.Payload as varType) != null); // after var q = ctx.Items.Where(i => i.Payload is TargetType).Select(i => (TargetType)i.Payload);
Defensive patterns
Strategy: validation
Validate before calling
// Reject anything other than a plain `as Type` before translation.
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
bool unsupportedAs = node.DescendantNodes().OfType<BinaryExpressionSyntax>()
.Any(b => b.IsKind(SyntaxKind.AsExpression)
&& !(b.Right is PredefinedTypeSyntax || b.Right is IdentifierNameSyntax || b.Right is QualifiedNameSyntax));
if (unsupportedAs)
throw new NotSupportedException("Only plain `x as T` conversions are supported in precompiled queries.");
translator.Translate(node, semanticModel); Try / catch
try { translator.Translate(node, semanticModel); }
catch (InvalidOperationException ex) when (ex.Message.Contains("AsExpression") && ex.Message.Contains("non-constant type"))
{ /* rewrite as a plain type conversion */ } Prevention
- Keep `as` expressions limited to `x as ConcreteType` inside queries.
- Avoid synthesized trees that put non-type nodes on the right of `as`.
When it happens
Trigger: A precompiled query using `as` with something other than a bare type reference, or where the translator cannot fold the right side to a constant `Type`.
Common situations: Complex generics or pattern-based `as` usage inside a query; usually the compiler keeps `as Type` simple, so this is rare in hand-written code but possible with generated/synthesized trees.
Related errors
- Encountered {SyntaxKind.IsExpression} with non-constant type
- Argument with ref/out: {argument}
- ArrayCreation: multi-dimensional array: {arrayCreation}
- BinaryExpressionSyntax with {binary.Kind()}
- ElementAccessExpressionSyntax over non-array
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/d2823f74cb60ed96.
Report an issue: GitHub.