dotnet/efcore · error · InvalidOperationException

AnonymousObjectCreation: unnamed initializer with non-Member

Error message

AnonymousObjectCreation: unnamed initializer with non-MemberAccess expression: {initializer.Expression}

What it means

For anonymous-object initializers without an explicit name (`NameEquals is null`), the translator infers the member name from a `MemberAccessExpressionSyntax` (mirroring the C# rule). If the initializer expression is neither named nor a member access, it throws `InvalidOperationException`. This matches C# projection-initializer rules, so the input would not normally compile — the guard catches malformed/synthesized trees.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:187

            throw new InvalidOperationException(DesignStrings.NoAnonymousSymbol + " " + anonymousObjectCreation);
        }

        var anonymousType = ResolveType(constructorSymbol.ContainingType);

        var parameters = constructorSymbol.Parameters.ToArray();

        var parameterInfos = new ParameterInfo[parameters.Length];
        var memberInfos = new MemberInfo[parameters.Length];
        var arguments = new Expression[parameters.Length];

        foreach (var initializer in anonymousObjectCreation.Initializers)
        {
            // If the initializer's name isn't explicitly specified, infer it from the initializer's expression like the compiler does
            var name = initializer.NameEquals is not null
                ? initializer.NameEquals.Name.Identifier.Text
                : initializer.Expression is MemberAccessExpressionSyntax memberAccess
                    ? memberAccess.Name.Identifier.Text
                    : throw new InvalidOperationException(
                        $"AnonymousObjectCreation: unnamed initializer with non-MemberAccess expression: {initializer.Expression}");

            var position = Array.FindIndex(parameters, p => p.Name == name);
            var parameter = parameters[position];
            var parameterType = ResolveType(parameter.Type)
                ?? throw new InvalidOperationException(
                    "Could not resolve type symbol for: " + parameter.Type);

            parameterInfos[position] = new FakeParameterInfo(name, parameterType, position);
            arguments[position] = Visit(initializer.Expression);
            memberInfos[position] = anonymousType.GetProperty(parameter.Name)!;
        }

        return New(
            new FakeConstructorInfo(anonymousType, parameterInfos),
            arguments: arguments,
            memberInfos);
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Give the initializer an explicit name: `new { name = expr }`.
  2. Or make the initializer a member access whose name can be inferred: `new { source.Member }`.
  3. If generating syntax trees programmatically, follow C# projection-initializer rules.

Example fix

// before
new { ctx.Method() }
// after
new { value = ctx.Method() }
Defensive patterns

Strategy: validation

Validate before calling

// For hand-built trees: ensure every anonymous initializer is nameable.
static bool IsNameable(AnonymousObjectMemberDeclaratorSyntax init)
    => init.NameEquals is not null
       || init.Expression is MemberAccessExpressionSyntax;

if (!anon.Initializers.All(IsNameable))
    throw new InvalidOperationException("Every anonymous initializer must have a name or be a member access.");

Prevention

When it happens

Trigger: Translating an anonymous-object creation whose initializer is a bare expression with no inferable name, e.g. a synthesized tree containing `new { SomeCall() }` rather than `new { x = SomeCall() }` or `new { a.Foo }`.

Common situations: Hand-built/synthesized syntax nodes passed to the translator, or a code generator emitting non-projection initializers. Normal compiled C# is rejected by the compiler first.

Related errors


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