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

Accessing the Builder of a StoredProcedureResultColumn that was removed from the model throws, because _builder is null. The result column is no longer part of the live metadata graph.

Solutions

  1. Do not cache result-column metadata across model mutations; re-query from the live procedure.
  2. Check resultColumn.IsInModel before accessing .Builder.
  3. Re-fetch via StoredProcedure.FindResultColumn(name).
  4. Ensure convention code runs before removal, or re-resolves references after.

Example fix

// before
var col = proc.ResultColumns[0];
proc.RemoveResultColumn(col.Name);
var b = col.Builder; // throws

// after
var col = proc.FindResultColumn(name);
if (col is { IsInModel: true })
{
    var b = col.Builder;
}
Defensive patterns

Strategy: validation

Validate before calling

if (resultColumn.IsInModel)
{
    var builder = resultColumn.Builder;
}

Type guard

static bool IsLiveResultColumn(StoredProcedureResultColumn c)
    => c.IsInModel;

Prevention

When it happens

Trigger: Holding a stale StoredProcedureResultColumn reference after it (or its procedure) was removed, then reading .Builder or invoking a builder API.

Common situations: Convention code caching result-column references across reconfigurations; removing a result column while another path still uses the reference; using metadata snapshots after the model was made read-only.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Metadata/Internal/StoredProcedureResultColumn.cs:49

        bool forRowsAffected,
        string? propertyName)
    {
        StoredProcedure = storedProcedure;
        ForRowsAffected = forRowsAffected;
        PropertyName = propertyName;
        _builder = new InternalStoredProcedureResultColumnBuilder(this, storedProcedure.Builder.ModelBuilder);
    }

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

    /// <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
            && StoredProcedure.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
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>

View on GitHub (pinned to 3a2006ef56)