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
- Always register and resolve the factory by a string provider name (the default API path).
- Use AddDynamoDBTransactionalStateStorage(name, ...) and resolve with the same string name.
- If you need a non-string key, wrap it: register under key.ToString() and document the mapping.
- 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
- Always register and resolve the factory by a string provider name.
- Avoid non-string keyed services for Orleans storage factories.
- Wrap non-string keys via .ToString() with documented mapping.
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
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Storage state corrupted: no record for committed state v{thi
- Load must be called after a failed Store before this storage
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/339b324e1a7fab89.
Report an issue: GitHub.