dotnet/orleans · error · InvalidOperationException

This instance has not been initialized. Ensure that Initiali

Error message

This instance has not been initialized. Ensure that InitializeMembershipTable is called to initialize this instance before use.

What it means

InvalidOperationException from the Session property getter on CassandraClusteringTable: the backing _session field is null because IMembershipTable.InitializeMembershipTable has not been called (or has not yet completed). The constant NotInitializedMessage names the exact method to call. This is a usage-ordering error, not a connectivity error.

Source

Thrown at src/Cassandra/Orleans.Clustering.Cassandra/CassandraClusteringTable.cs:38

    private readonly IServiceProvider _serviceProvider;
    private ISession? _session;
    private OrleansQueries? _queries;
    private readonly string _identifier;

    public CassandraClusteringTable(
        IOptions<ClusterOptions> clusterOptions,
        IOptions<CassandraClusteringOptions> options,
        IOptions<ClusterMembershipOptions> clusterMembershipOptions,
        IServiceProvider serviceProvider)
    {
        _clusterOptions = clusterOptions.Value;
        _options = options.Value;
        _identifier = $"{_clusterOptions.ServiceId}-{_clusterOptions.ClusterId}";
        _serviceProvider = serviceProvider;
        _ttlSeconds = _options.GetCassandraTtlSeconds(clusterMembershipOptions.Value);
    }

    private ISession Session => _session ?? throw new InvalidOperationException(NotInitializedMessage);

    private OrleansQueries Queries => _queries ?? throw new InvalidOperationException(NotInitializedMessage);

    async Task IMembershipTable.InitializeMembershipTable(bool tryInitTableVersion)
    {
        _session = await _options.CreateSessionAsync(_serviceProvider);
        if (_session is null)
        {
            throw new InvalidOperationException($"Session created from configuration '{nameof(CassandraClusteringOptions)}' is null.");
        }

        _queries = await OrleansQueries.CreateInstance(_session);

        await _queries.EnsureTableExistsAsync(_options.InitializeRetryMaxDelay, _ttlSeconds);

        if (tryInitTableVersion)
            await _queries.EnsureClusterVersionExistsAsync(_options.InitializeRetryMaxDelay, _identifier);
    }

View on GitHub (pinned to fca799fa70)

Solutions

  1. Ensure the Orleans hosting extension (UseCassandraClustering / AddCassandraClustering) is registered so the runtime invokes InitializeMembershipTable during silo startup.
  2. Await InitializeMembershipTable before any membership call in tests/integration code.
  3. If initialization is failing earlier, check the log for the exception from CreateSessionAsync (which sets _session); fixing that resolves this secondary error.

Example fix

// before (test)
var table = host.Services.GetRequiredService<IMembershipTable>();
await table.ReadAll(); // throws: Session null

// after
var table = host.Services.GetRequiredService<IMembershipTable>();
await table.InitializeMembershipTable(tryInitTableVersion: true);
await table.ReadAll();
Defensive patterns

Strategy: validation

Validate before calling

await table.InitializeMembershipTable(tryInitTableVersion: true);
// guard before use if you cannot guarantee init order:
if (!initialized) throw new InvalidOperationException("init first");

Try / catch

try { await table.ReadAll(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("InitializeMembershipTable"))
{
    logger.LogError(ex, "Membership table used before initialization"); throw;
}

Prevention

When it happens

Trigger: Any membership operation (ReadAll, ReadRow, InsertRow, etc.) that touches the Session property before InitializeMembershipTable finishes assigning _session. The property is accessed on every query execution.

Common situations: Calling membership methods in a test without awaiting initialization, a DI/registration order problem where the table is resolved and used before the hosting pipeline runs initialization, or InitializeMembershipTable throwing earlier (e.g. CreateSessionAsync failed) leaving _session null.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/6bef3eb7247ad51e. Report an issue: GitHub.