dotnet/efcore · error · NotSupportedException
Missing default arm for switch expression
Error message
Missing default arm for switch expression
What it means
In expression context a C# switch expression must be exhaustive and therefore requires a discard (_) arm. If switchNode.DefaultBody is null the translator cannot emit a valid switch expression, so it throws NotSupportedException. (In statement context a missing default is allowed, so this only fires for value-returning switches.)
Source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:2257
var result = translatedBody switch
{
BlockSyntax block => SingletonList<StatementSyntax>(block.WithStatements(block.Statements.Add(BreakStatement()))),
StatementSyntax s => List([s, BreakStatement()]),
ExpressionSyntax e => List(new StatementSyntax[] { ExpressionStatement(e), BreakStatement() }),
_ => throw new ArgumentOutOfRangeException()
};
return result;
}
}
case ExpressionContext.Expression:
case ExpressionContext.ExpressionLambda:
{
if (switchNode.DefaultBody is null)
{
throw new NotSupportedException("Missing default arm for switch expression");
}
var parentLiftedState = _liftedState;
_liftedState = parentLiftedState.CreateChild();
// Translate all arms
var arms = SeparatedList(
switchNode.Cases.SelectMany(
c => c.TestValues, (c, tv) => SwitchExpressionArm(
ConstantPattern(Translate<ExpressionSyntax>(tv)),
Translate<ExpressionSyntax>(c.Body)))
.Append(SwitchExpressionArm(DiscardPattern(), Translate<ExpressionSyntax>(switchNode.DefaultBody))));
// LINQ SwitchExpression supports non-literal labels, which C# does not support. This rewrites the switch as a series of
// nested ConditionalExpressions.
if (arms.Any(a => a.Pattern is ConstantPatternSyntax cp && !_constantDetector.IsConstant(cp.Expression)))
{
_liftedState = parentLiftedState;View on GitHub (pinned to dbf9771522)
Solutions
- Provide a default body: Expression.Switch(value, defaultBody, cases).
- Use the switch in statement context (where a default is optional) instead of as a value.
- Rewrite as nested Conditional (Expression.Condition) expressions which can omit a final fallback.
Example fix
// before
var sw = Expression.Switch(value, new[] { case1, case2 }); // no default body -> throws as value
// after
var sw = Expression.Switch(value, Expression.Constant(0), new[] { case1, case2 }); Defensive patterns
Strategy: validation
Validate before calling
// If a switch is used as a value, ensure it has a default body
protected override Expression VisitSwitch(SwitchExpression s) {
if (s.DefaultBody is null && s.Type != typeof(void)) Found = true;
return s;
} Prevention
- Always supply a default body for value-returning switches.
- Use statement-context switches where a default is optional.
- Fall back to nested Conditional expressions if no default fits.
When it happens
Trigger: A SwitchExpression used as a value (e.g. inside a Select projection, in Expression/ExpressionLambda context) that has no default body.
Common situations: Building Expression.Switch(value, cases) without the default-body argument and then using the result as a value in a compiled query.
Related errors
- Switch with non-null comparison method
- Empty switch statement
- Null argument in VisitLabelTarget
- Non-void label target
- DebugInfo nodes are not supporting when translating expressi
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/2e59e031108e7d70.
Report an issue: GitHub.