dotnet/orleans · error · InvalidOperationException

The transactional state storage provider name is required.

Error message

The transactional state storage provider name is required.

What it means

Thrown inside the keyed-singleton factory registered by AddDynamoDBTransactionalStateStorage when the DI service key is not a string. Orleans registers transactional state storage by provider name (a string); resolving ITransactionalStateStorageFactory with a non-string key means the registration was misused or the keyed-service lookup bypassed the documented API.

Source

Thrown at src/AWS/Orleans.Transactions.DynamoDB/Hosting/DynamoDBTransactionServiceCollectionExtensions.cs:32

/// <summary>
/// <see cref="IServiceCollection"/> extensions.
/// </summary>
public static class DynamoDBTransactionServiceCollectionExtensions
{
    internal static IServiceCollection AddDynamoDBTransactionalStateStorage(this IServiceCollection services,
        string name,
        Action<OptionsBuilder<DynamoDBTransactionalStorageOptions>>? configureOptions = null)
    {
        configureOptions?.Invoke(services.AddOptions<DynamoDBTransactionalStorageOptions>(name));
        services.AddTransient<IConfigurationValidator>(sp => new DynamoDBTransactionalStorageOptionsValidator(sp.GetRequiredService<IOptionsMonitor<DynamoDBTransactionalStorageOptions>>().Get(name), name));
        services.ConfigureNamedOptionForLogging<DynamoDBTransactionalStorageOptions>(name);
        services.AddTransient<IPostConfigureOptions<DynamoDBTransactionalStorageOptions>, DefaultStorageProviderSerializerOptionsConfigurator<DynamoDBTransactionalStorageOptions>>();

        services.TryAddSingleton<ITransactionalStateStorageFactory>(sp => sp.GetRequiredKeyedService<ITransactionalStateStorageFactory>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
        services.AddKeyedSingleton<ITransactionalStateStorageFactory>(name, (sp, key) =>
            DynamoDBTransactionalStateStorageFactory.Create(
                sp,
                key as string ?? throw new InvalidOperationException("The transactional state storage provider name is required.")));
        services.AddSingleton<ILifecycleParticipant<ISiloLifecycle>>(s => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredKeyedService<ITransactionalStateStorageFactory>(name));

        return services;
    }
}

View on GitHub (pinned to fca799fa70)

Solutions

  1. Always register and resolve the factory by a string provider name (the default API path).
  2. Use AddDynamoDBTransactionalStateStorage(name, ...) and resolve with the same string name.
  3. If you need a non-string key, wrap it: register under key.ToString() and document the mapping.
  4. Audit custom hosting extensions for non-string keyed registrations of this factory.

Example fix

// before
sp.GetRequiredKeyedService<ITransactionalStateStorageFactory>(42); // non-string key -> throws

// after
sp.GetRequiredKeyedService<ITransactionalStateStorageFactory>("myTxStore");
Defensive patterns

Strategy: validation

Validate before calling

string name = key as string ?? throw new InvalidOperationException("Provider name must be a string.");
var factory = sp.GetRequiredKeyedService<ITransactionalStateStorageFactory>(name);

Type guard

static bool IsStringKey(object? key) => key is string s && !string.IsNullOrWhiteSpace(s);

Try / catch

try { var f = sp.GetRequiredKeyedService<ITransactionalStateStorageFactory>(name); }
catch (InvalidOperationException ex) when (ex.Message.Contains("provider name is required"))
{
    logger.LogCritical("Resolved transactional storage factory with a non-string key.");
    throw;
}

Prevention

When it happens

Trigger: Manually resolving ITransactionalStateStorageFactory via GetRequiredKeyedService with a non-string key (e.g., an enum, int, or Type), or a custom hosting extension that registers the factory under a non-string key.

Common situations: Custom DI wiring that uses non-string keyed services; experimental code resolving the factory directly; .NET 8+ keyed DI used with a non-string key by mistake.

Related errors


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