dotnet/efcore · error · NotImplementedException

Non-void label target

Error message

Non-void label target

What it means

TranslateLabelTarget throws NotImplementedException for any label target whose Type is not void. LINQ label targets can carry a return type (the value a block evaluates to when control reaches the label), but C# labels cannot return values, so faithfully translating this would require hoisting the last evaluation into a temp before the goto and reading it after the label — logic the translator does not implement.

Source

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

        Result = TranslateLabelTarget(labelTarget);
        return labelTarget;
    }

    /// <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>
    protected virtual IdentifierNameSyntax TranslateLabelTarget(LabelTarget labelTarget)
    {
        // In LINQ expression trees, label targets can have a return type (they're expressions), which means they return the last evaluated
        // thing if e.g. they're the last expression in a block. This would require lifting out the last evaluation before the goto/break,
        // assigning it to a temporary variable, and adding a variable evaluation after the label.
        if (labelTarget.Type != typeof(void))
        {
            throw new NotImplementedException("Non-void label target");
        }

        // We did a processing pass on the block's labels, so any labels should already be found in our label stack frame
        return IdentifierName(_stack.Peek().Labels[labelTarget]);
    }

    /// <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>
    protected virtual TypeSyntax Generate(Type type)
        => TryGenerate(type, out var result)
            ? result
            : throw new NotSupportedException(DesignStrings.UnableToTranslateType(type.DisplayName(fullName: false)));

    /// <summary>

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use void label targets: Expression.Label(typeof(void)).
  2. Restructure so the value is written to a separate ParameterExpression before the goto and read after the label.
  3. Avoid value-returning label control flow inside precompiled query / model lambdas.

Example fix

// before
var ret = Expression.Label(typeof(int), "ret");
// after
var result = Expression.Parameter(typeof(int), "result");
var ret = Expression.Label(typeof(void), "ret");
Defensive patterns

Strategy: validation

Validate before calling

public sealed class TypedLabelDetector : ExpressionVisitor {
    public bool Found;
    protected override Expression VisitLabel(LabelExpression l) { if (l.Target?.Type is { } t && t != typeof(void)) Found = true; return l; }
}

Prevention

When it happens

Trigger: An expression tree uses a non-void label target such as Expression.Label(typeof(int), "name"). Occurs in value-returning goto-based control flow built programmatically.

Common situations: Custom expression trees that model computed-goto with return values; rarely if ever from compiler-generated query lambdas.

Related errors


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