dotnet/efcore · error · InvalidOperationException

The object ' ' has been removed from the model.

Error message

The object '{name}' has been removed from the model.

What it means

An EntityTypeMappingFragment (the per-store-object mapping slice for an entity) tracks whether it is still attached to the model via its _builder field. Accessing the Builder after the fragment has been removed throws ObjectRemovedFromModel, signaling stale metadata use.

Solutions

  1. Do not retain fragment references across model mutations; fetch them fresh from the current entity type after any model change.
  2. Before accessing Builder, check fragment.IsInModel (which returns _builder is not null).
  3. Reorder configuration so removals happen last and no later code touches removed fragments.

Example fix

// before
var fragment = entityType.FindMappingFragment(table);
modelBuilder.Entity<Order>().Ignore(...); // invalidates fragment
var b = fragment.Builder; // throws

// after
modelBuilder.Entity<Order>().Ignore(...);
var freshFragment = modelBuilder.Entity<Order>().Metadata.FindMappingFragment(table);
var b = freshFragment?.IsInModel == true ? freshFragment.Builder : null;
Defensive patterns

Strategy: type-guard

Validate before calling

var fragment = entityType.FindMappingFragment(table);
if (fragment is { IsInModel: true } attached)
{
    var builder = attached.Builder;
}

Type guard

static bool IsFragmentAttached(IReadOnlyEntityTypeMappingFragment f)
    => f is EntityTypeMappingFragment { IsInModel: true };

Prevention

When it happens

Trigger: Holding a reference to a fragment returned by EntityType.MappingFragment or IReadOnlyEntityType.FindMappingFragment and then calling modelBuilder to remove it (or removing the entity/store object) before accessing its Builder.

Common situations: Conditional model building where a fragment is added then removed in a later pass; caching metadata objects across model rebuilds; using a fragment after EntityType.SetMappingFragment(null, ...).

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/8e84b83148a0da57. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/EntityTypeMappingFragment.cs:51

        ConfigurationSource configurationSource)
    {
        EntityType = entityType;
        StoreObject = storeObject;
        _configurationSource = configurationSource;
        _builder = new InternalEntityTypeMappingFragmentBuilder(this, ((IConventionModel)entityType.Model).Builder);
    }

    /// <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 InternalEntityTypeMappingFragmentBuilder Builder
    {
        [DebuggerStepThrough]
        get => _builder
            ?? throw new InvalidOperationException(
                CoreStrings.ObjectRemovedFromModel(
                    StoreObject.DisplayName()));
    }

    /// <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 bool IsInModel
        => _builder is not null
            && ((IConventionAnnotatable)EntityType).IsInModel;

    /// <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

View on GitHub (pinned to 3a2006ef56)