{"record":{"id":"8602eb58147b05cb","repo":"dotnet/orleans","slug":"nameof-adonetqueueadapter-does-not-support-a-us","errorCode":null,"errorMessage":"{nameof(AdoNetQueueAdapter)} does not support a user supplied {nameof(StreamSequenceToken)}.","messagePattern":"(.+?) does not support a user supplied (.+?)\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/AdoNet/Orleans.Streaming.AdoNet/AdoNetQueueAdapter.cs","lineNumber":39,"sourceCode":"    /// The ADO.NET provider works both ways.\n    /// </summary>\n    public StreamProviderDirection Direction => StreamProviderDirection.ReadWrite;\n\n    public IQueueAdapterReceiver CreateReceiver(QueueId queueId)\n    {\n        // map the queue id\n        var adoNetQueueId = mapper.GetAdoNetQueueId(queueId);\n\n        // create the receiver\n        return ReceiverFactory(serviceProvider, [Name, adoNetQueueId, streamOptions, clusterOptions, cacheOptions, queries]);\n    }\n\n    public async Task QueueMessageBatchAsync<T>(StreamId streamId, IEnumerable<T> events, StreamSequenceToken? token, Dictionary<string, object>? requestContext)\n    {\n        // the ADO.NET provider is not rewindable so we do not support user supplied tokens\n        if (token is not null)\n        {\n            throw new ArgumentException($\"{nameof(AdoNetQueueAdapter)} does not support a user supplied {nameof(StreamSequenceToken)}.\");\n        }\n\n        // map the Orleans stream id to the corresponding queue id\n        var queueId = mapper.GetAdoNetQueueId(streamId);\n\n        // create the payload from the events\n        var payload = AdoNetBatchContainer.ToMessagePayload(serializer, streamId, events.Cast<object>().ToList(), requestContext);\n\n        // we can enqueue the message now\n        try\n        {\n            await queries.QueueStreamMessageAsync(clusterOptions.ServiceId, Name, queueId, payload, streamOptions.ExpiryTimeout.TotalSecondsCeiling());\n        }\n        catch (Exception ex)\n        {\n            LogFailedToQueueStreamMessage(ex, clusterOptions.ServiceId, Name, queueId);\n            throw;\n        }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/AdoNet/Orleans.Streaming.AdoNet/AdoNetQueueAdapter.cs#L21-L57","documentation":"Thrown by AdoNetQueueAdapter.QueueMessageBatchAsync when the caller supplies a non-null StreamSequenceToken. The ADO.NET streaming provider is non-rewindable: it cannot replay from an arbitrary offset, so user-supplied tokens are unsupported and rejected upfront rather than silently ignored.","triggerScenarios":"QueueMessageBatchAsync is called with a non-null token argument. In normal Orleans usage the streaming runtime passes null for the token on a non-rewindable provider, so this fires only if custom code drives the adapter directly with a token.","commonSituations":"Custom producer code calling the queue adapter with a checkpoint token; porting rewindable-provider code (e.g. Azure Event Hubs) to ADO.NET without dropping the token; an IStreamQueueMapper/adapter wrapper forwarding tokens.","solutions":["Pass null for the StreamSequenceToken when producing to the ADO.NET adapter.","If you need rewindability, switch to a rewindable streaming provider instead of ADO.NET.","Audit any custom producer/adapter wrapper to ensure it forwards null tokens to ADO.NET."],"exampleFix":"// before\nawait adapter.QueueMessageBatchAsync(streamId, events, new EventSequenceTokenV2(5), requestContext);\n\n// after\nawait adapter.QueueMessageBatchAsync(streamId, events, token: null, requestContext);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// ADO.NET adapter is non-rewindable; only null tokens are valid.\nstatic bool IsValidTokenForAdoNet(StreamSequenceToken? token) => token is null;","tryCatchPattern":"try { await adapter.QueueMessageBatchAsync(streamId, events, token, ctx); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not support a user supplied\"))\n{\n    // drop the token and retry with null.\n}","preventionTips":["Pass null as the token when producing to the ADO.NET stream adapter.","If rewindability is required, choose a rewindable provider instead of ADO.NET.","Audit custom adapter wrappers to forward null tokens."],"tags":["adonet","streaming","queue-adapter","sequence-token","runtime"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}