{"record":{"id":"21d26fbfcd9acfb0","repo":"dotnet/orleans","slug":"dynamodbstorage-client-is-not-initialized","errorCode":null,"errorMessage":"DynamoDBStorage client is not initialized","messagePattern":"DynamoDBStorage client is not initialized","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorageFactory.cs","lineNumber":80,"sourceCode":"\n    /// <summary>\n    /// Creates a transactional state storage factory.\n    /// </summary>\n    /// <param name=\"services\">The service provider.</param>\n    /// <param name=\"name\">The provider name.</param>\n    /// <returns>The transactional state storage factory.</returns>\n    public static ITransactionalStateStorageFactory Create(IServiceProvider services, string name)\n    {\n        var optionsMonitor = services.GetRequiredService<IOptionsMonitor<DynamoDBTransactionalStorageOptions>>();\n        return ActivatorUtilities.CreateInstance<DynamoDBTransactionalStateStorageFactory>(services, name, optionsMonitor.Get(name));\n    }\n\n    /// <inheritdoc />\n    public ITransactionalStateStorage<TState> Create<TState>(string stateName, IGrainContext context) where TState : class, new()\n    {\n        if (this.storage is null)\n        {\n            throw new ArgumentException(\"DynamoDBStorage client is not initialized\");\n        }\n\n        var partitionKey = this.MakePartitionKey(context, stateName);\n        var logger = this.loggerFactory.CreateLogger<DynamoDBTransactionalStateStorage<TState>>();\n        return ActivatorUtilities.CreateInstance<DynamoDBTransactionalStateStorage<TState>>(context.ActivationServices, this.storage, this.options, partitionKey, logger);\n    }\n\n    /// <inheritdoc />\n    public void Participate(ISiloLifecycle lifecycle)\n    {\n        lifecycle.Subscribe(OptionFormattingUtilities.Name<DynamoDBTransactionalStateStorageFactory>(this.name), this.options.InitStage, Init);\n    }\n\n    private async Task Initialize(CancellationToken cancellationToken)\n    {\n        var stopWatch = Stopwatch.StartNew();\n        var logger = this.loggerFactory.CreateLogger<DynamoDBStorage>();\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorageFactory.cs#L62-L98","documentation":"Thrown by DynamoDBTransactionalStateStorageFactory.Create<TState> when this.storage is still null. storage is assigned inside the lifecycle Init handler (Initialize), so a null storage means the silo lifecycle never reached the configured InitStage for this provider, or that Init threw and the factory is still being asked to create storage instances. It is an ordering/initialization-failure guard.","triggerScenarios":"Produced when a grain requests its transactional storage before the provider's Init stage ran (InitStage misconfigured to a late stage while grains activate earlier), or after Init failed (e.g., the DynamoDBStorage constructor threw because of bad credentials/region) but grain activation continues. Also seen if the provider was not registered correctly.","commonSituations":"InitStage set later than the grain-collection stage; DynamoDB connectivity/credentials failing during silo startup so Initialize() threw; misregistration of the transactional storage provider; running against DynamoDB Local that is not reachable.","solutions":["Check the silo startup logs for an earlier 'Initialization failed for provider ...' (LogErrorProviderInitFailed) message — the real cause is upstream in Init.","Verify DynamoDBTransactionalStorageOptions (Service/region, credentials, TableName) are correct and that the table can be created/reached.","Ensure InitStage is early enough that the provider is initialized before grains that use it activate.","Confirm the provider is registered via AddDynamoDBTransactionalGrainStorageAsDefault / the named variant in the silo builder."],"exampleFix":"// before: provider never initialized because options were wrong or stage too late\nsilo.AddDynamoDBTransactionalGrainStorage(\"txStore\", opt =>\n{\n    opt.Service = \"\"; // empty region -> default, but maybe wrong table\n});\n\n// after: supply a valid region, table, and an early init stage\nsilo.AddDynamoDBTransactionalGrainStorage(\"txStore\", opt =>\n{\n    opt.Service = \"us-west-2\";\n    opt.TableName = \"OrleansTransactionalState\";\n    opt.InitStage = ServiceLifecycleStage.RuntimeInitialize; // earlier than grain activation\n});","handlingStrategy":"validation","validationCode":"// Verify the provider is registered and will init before grains activate\nvar monitor = services.GetRequiredService<IOptionsMonitor<DynamoDBTransactionalStorageOptions>>();\nvar opt = monitor.Get(\"txStore\");\nif (string.IsNullOrWhiteSpace(opt.Service))\n    throw new InvalidOperationException(\"DynamoDB transactional storage 'Service' (region) is not set\");","typeGuard":"static bool IsProviderInitialized(DynamoDBTransactionalStateStorageFactory f) =>\n    typeof(DynamoDBTransactionalStateStorageFactory)\n        .GetField(\"storage\", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(f) is not null;","tryCatchPattern":"try { await client.GetGrain<IMyGrain>(key).DoWork(); }\ncatch (ArgumentException ax) when (ax.Message == \"DynamoDBStorage client is not initialized\")\n{\n    _logger.LogCritical(\"Transactional storage provider failed to initialize; check silo startup logs\");\n    throw;\n}","preventionTips":["Register the provider with AddDynamoDBTransactionalGrainStorage(AsDefault) in the silo builder.","Set InitStage early enough that Init runs before grain activation.","Always check silo startup logs for 'Initialization failed for provider' before assuming grains work.","Validate region/credentials/table options in a bootstrap check before silo.StartAsync()."],"tags":["dynamodb","transactions","lifecycle","initialization","factory"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}