dotnet/efcore · error · ArgumentException

A type-qualified method call requires an instance identifier

Error message

A type-qualified method call requires an instance identifier, a MethodInfo and no chained calls.

What it means

Thrown as ArgumentException by CSharpHelper.Fragment when typeQualified is true but the method-call fragment cannot be emitted as a type-qualified call. A type-qualified call (e.g., 'DbContextOptions.UseSqlite(x, ...)') requires three things: a non-null instanceIdentifier, a non-null fragment.DeclaringType, and no ChainedCall (chained fluent calls cannot be type-qualified). Violating any one rejects the request.

Source

Thrown at src/EFCore.Design/Design/Internal/CSharpHelper.cs:1272

        return true;
    }

    /// <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 virtual string Fragment(IMethodCallCodeFragment fragment, string? instanceIdentifier, bool typeQualified)
    {
        var builder = new StringBuilder();

        if (typeQualified)
        {
            if (instanceIdentifier is null || fragment.DeclaringType is null || fragment.ChainedCall is not null)
            {
                throw new ArgumentException(DesignStrings.CannotGenerateTypeQualifiedMethodCall);
            }

            builder
                .Append(fragment.DeclaringType)
                .Append('.')
                .Append(fragment.Method)
                .Append('(')
                .Append(instanceIdentifier);

            foreach (var argument in fragment.Arguments)
            {
                builder.Append(", ");

                if (argument is NestedClosureCodeFragment nestedFragment)
                {
                    builder.Append(Fragment(nestedFragment, 1));
                }
                else

View on GitHub (pinned to dbf9771522)

Solutions

  1. Do not pass typeQualified: true for chained fragments; emit them as instance calls instead.
  2. Ensure the fragment has a DeclaringType set and pass a non-null instanceIdentifier when using typeQualified mode.
  3. If chaining is intentional, drop the typeQualified flag and use the instance-identifier overload.

Example fix

// before - type-qualified call attempted on a chained fragment
helper.Fragment(chainedFragment, instanceIdentifier, typeQualified: true); // throws

// after - use instance mode for chained calls
helper.Fragment(chainedFragment, instanceIdentifier, typeQualified: false);
Defensive patterns

Strategy: validation

Validate before calling

// Only use typeQualified mode when all preconditions hold.
if (fragment.DeclaringType is not null && instanceIdentifier is not null && fragment.ChainedCall is null)
{
    helper.Fragment(fragment, instanceIdentifier, typeQualified: true);
}
else
{
    helper.Fragment(fragment, instanceIdentifier, typeQualified: false);
}

Try / catch

try { helper.Fragment(fragment, instanceIdentifier, typeQualified: true); }
catch (ArgumentException ex) when (ex.Message.Contains("type-qualified method call"))
{
    helper.Fragment(fragment, instanceIdentifier, typeQualified: false);
}

Prevention

When it happens

Trigger: Calling the internal Fragment(fragment, instanceIdentifier, typeQualified: true) with a null instance identifier, a fragment whose DeclaringType is null, or a fragment that has a ChainedCall. Reached during code generation that needs to emit a static-style method call referencing the instance as the first argument.

Common situations: A provider/plugin calling Fragment in type-qualified mode with a chained code fragment (which only makes sense for fluent 'builder.X().Y()' emissions). Passing an IMethodCallCodeFragment that did not set DeclaringType. Building custom migrations/annotation code generators that misuse the typeQualified path.

Related errors


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