dotnet/efcore · error · NotImplementedException
Power over non-double operands
Error message
Power over non-double operands
What it means
Thrown by VisitBinary for ExpressionType.Power when operands are not both double. Only double operands are supported (translated to a Math.Pow call); other numeric types are not auto-converted. Part of EF Core's LINQ-to-C# syntax translation.
Source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:337
case ExpressionType.OrAssign:
return VisitAssignment(binary, SyntaxKind.OrAssignmentExpression);
case ExpressionType.LeftShiftAssign:
return VisitAssignment(binary, SyntaxKind.LeftShiftAssignmentExpression);
case ExpressionType.RightShiftAssign:
return VisitAssignment(binary, SyntaxKind.RightShiftAssignmentExpression);
case ExpressionType.ExclusiveOrAssign:
return VisitAssignment(binary, SyntaxKind.ExclusiveOrAssignmentExpression);
case ExpressionType.Power when binary.Left.Type == typeof(double) && binary.Right.Type == typeof(double):
return Visit(
Expression.Call(
_mathPowMethod ??= typeof(Math).GetMethod(
nameof(Math.Pow), BindingFlags.Static | BindingFlags.Public, [typeof(double), typeof(double)])!,
binary.Left,
binary.Right));
case ExpressionType.Power:
throw new NotImplementedException("Power over non-double operands");
case ExpressionType.PowerAssign:
return Visit(
Expression.Assign(
binary.Left,
Expression.Power(
binary.Left,
binary.Right)));
}
var liftedStatementOrigPosition = _liftedState.Statements.Count;
var left = Translate<ExpressionSyntax>(binary.Left);
var liftedStatementLeftPosition = _liftedState.Statements.Count;
var right = Translate<ExpressionSyntax>(binary.Right);
// If both sides were lifted, we don't need to do anything special. Same if the left side was lifted.
// But if the right side was lifted and the left wasn't, then in order to preserve evaluation order we need to lift the left side
// out as well, otherwise the right side gets evaluated before the left.View on GitHub (pinned to dbf9771522)
Solutions
- Cast both operands to double before constructing Expression.Power.
- Use Math.Pow directly with double operands.
Example fix
// before
Expression.Power(leftInt, rightInt)
// after
Expression.Power(
Expression.Convert(leftInt, typeof(double)),
Expression.Convert(rightInt, typeof(double))) Defensive patterns
Strategy: validation
Validate before calling
// Validate Power operands are double before building the expression
if (binary.NodeType == ExpressionType.Power
&& (binary.Left.Type != typeof(double) || binary.Right.Type != typeof(double)))
{
binary = Expression.Power(
Expression.Convert(binary.Left, typeof(double)),
Expression.Convert(binary.Right, typeof(double)));
} Prevention
- Always convert operands to double before Expression.Power.
- In query translators, normalize numeric operands to double for exponentiation.
When it happens
Trigger: An expression tree containing Expression.Power (or PowerAssign) with non-double operand types such as int, float, or decimal.
Common situations: Building expression trees programmatically with Expression.Power over integers; query translators emitting Power with the wrong operand types.
Related errors
- Got translated node of type '{Result?.GetType().Name ?? "<nu
- Lambda with null expression body
- Lambda with modifiers not supported: {lambda.Modifiers}
- Async lambdas are not supported
- Lifted expressions remaining at top-level in expression cont
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/8171278b9ebd1cf9.
Report an issue: GitHub.