{"record":{"id":"023b262d0190b175","repo":"dotnet/orleans","slug":"checkpointerfactory","errorCode":null,"errorMessage":"checkpointerFactory","messagePattern":"checkpointerFactory","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs","lineNumber":103,"sourceCode":"                monitor,\n                loadSheddingOptions,\n                environmentStatisticsProvider,\n                eventHubReceiverFactory)\n        {\n        }\n\n        public EventHubAdapterReceiver(EventHubPartitionSettings settings,\n            Func<string, IStreamQueueCheckpointer<string>, ILoggerFactory, IEventHubQueueCache> cacheFactory,\n            Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> checkpointerFactory,\n            ILoggerFactory loggerFactory,\n            IQueueAdapterReceiverMonitor monitor,\n            LoadSheddingOptions loadSheddingOptions,\n            IEnvironmentStatisticsProvider environmentStatisticsProvider,\n            Func<EventHubPartitionSettings, string, ILogger, IEventHubReceiver>? eventHubReceiverFactory = null)\n        {\n            this.settings = settings ?? throw new ArgumentNullException(nameof(settings));\n            this.cacheFactory = cacheFactory ?? throw new ArgumentNullException(nameof(cacheFactory));\n            this.checkpointerFactory = checkpointerFactory ?? throw new ArgumentNullException(nameof(checkpointerFactory));\n            this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));\n            this.logger = this.loggerFactory.CreateLogger<EventHubAdapterReceiver>();\n            this.monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));\n            this.loadSheddingOptions = loadSheddingOptions ?? throw new ArgumentNullException(nameof(loadSheddingOptions));\n            this.environmentStatisticsProvider = environmentStatisticsProvider;\n            this.eventHubReceiverFactory = eventHubReceiverFactory == null ? EventHubAdapterReceiver.CreateReceiver : eventHubReceiverFactory;\n        }\n\n        public async Task Initialize(TimeSpan timeout)\n        {\n            LogInfoInitializingEventHubPartition(this.settings.Hub.EventHubName, this.settings.Partition);\n\n            // if receiver was already running, do nothing\n            if (ReceiverRunning == Interlocked.Exchange(ref this.receiverState, ReceiverRunning))\n            {\n                return;\n            }\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs#L85-L121","documentation":"EventHubAdapterReceiver requires a non-null checkpointerFactory delegate because it is called during Initialize to create an IStreamQueueCheckpointer<string> that loads and persists the Event Hub offset for the partition. Without checkpointing the receiver would re-read from the start of the partition on every restart, causing duplicate processing. The factory is invoked as checkpointerFactory(settings.Partition, cancellationToken) to produce the checkpointer.","triggerScenarios":"Constructing EventHubAdapterReceiver with checkpointerFactory set to null. In the factory path, the checkpointer factory is passed from EventHubAdapterFactory.MakeReceiver as (partition, ct) => this.checkpointerFactory.Create(partition, ct), where checkpointerFactory is resolved from keyed DI services. Fires on direct construction or when the IStreamQueueCheckpointerFactory is not registered in DI.","commonSituations":"Forgetting to register a checkpointer provider (e.g., Azure Blob Storage checkpointer) in the Event Hub stream configuration; manual construction in tests without a checkpointer; the IStreamQueueCheckpointerFactory keyed service is missing from DI, though in that case StreamCheckpointerConfigurationValidator would typically catch it first.","solutions":["Ensure a stream checkpointer is configured, e.g., by calling the appropriate checkpointer configuration extension on the Event Hub stream provider.","If constructing manually, pass a Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> that returns a valid checkpointer (e.g., a mock in tests).","Verify StreamCheckpointerConfigurationValidator passes during silo startup — it checks for IStreamQueueCheckpointerFactory keyed services."],"exampleFix":"// before\nvar receiver = new EventHubAdapterReceiver(\n    settings, cacheFactory, null /* checkpointerFactory */, ...);\n\n// after\nFunc<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> checkpointerFactory =\n    async (partition, ct) =>\n    {\n        var checkpointer = new MockCheckpointer();\n        await checkpointer.Load(ct);\n        return checkpointer;\n    };\nvar receiver = new EventHubAdapterReceiver(\n    settings, cacheFactory, checkpointerFactory, ...);","handlingStrategy":"validation","validationCode":"// Verify checkpointer factory is non-null:\nif (checkpointerFactory is null)\n    throw new InvalidOperationException(\n        \"A checkpointer factory is required. Ensure IStreamQueueCheckpointerFactory \" +\n        \"is registered in DI for this stream provider.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure a stream checkpointer (e.g., Azure Blob Storage based) when setting up Event Hub streams.","Verify StreamCheckpointerConfigurationValidator passes during silo startup.","In tests, pass a Func<string, CancellationToken, Task<IStreamQueueCheckpointer<string>>> that returns a mock checkpointer."],"tags":["configuration","eventhub","constructor","null-argument","receiver","checkpointer"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}