{"record":{"id":"70d07945dc33623e","repo":"dotnetcore/CAP","slug":"value-cannot-be-null-parameter-topics","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'topics')","messagePattern":"Value cannot be null\\. \\(Parameter 'topics'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/DotNetCore.CAP.AmazonSQS/AmazonSQSConsumerClient.cs","lineNumber":71,"sourceCode":"\n        var topicArns = new List<string>();\n        foreach (var topic in topicNames)\n        {\n            var createTopicRequest = new CreateTopicRequest(topic.NormalizeForAws());\n\n            var createTopicResponse = await _snsClient!.CreateTopicAsync(createTopicRequest).ConfigureAwait(false);\n\n            topicArns.Add(createTopicResponse.TopicArn);\n        }\n\n        await GenerateSqsAccessPolicyAsync(topicArns).ConfigureAwait(false);\n\n        return topicArns;\n    }\n\n    public async Task SubscribeAsync(IEnumerable<string> topics)\n    {\n        if (topics == null) throw new ArgumentNullException(nameof(topics));\n\n        await ConnectAsync().ConfigureAwait(false);\n\n        await SubscribeToTopics(topics).ConfigureAwait(false);\n    }\n\n    public async Task ListeningAsync(TimeSpan timeout, CancellationToken cancellationToken)\n    {\n        await ConnectAsync().ConfigureAwait(false);\n\n        var request = new ReceiveMessageRequest(_queueUrl)\n        {\n            WaitTimeSeconds = 5,\n            MaxNumberOfMessages = 1\n        };\n\n        while (true)\n        {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/dotnetcore/CAP/blob/e52b8508e54cdb7a9ce7f9fec03d9ea8ad2710fb/src/DotNetCore.CAP.AmazonSQS/AmazonSQSConsumerClient.cs#L53-L89","documentation":"SubscribeAsync requires a non-null collection of topic names to create SNS topics/subscribe SQS queues. It throws ArgumentNullException when topics is null, distinguishing 'null' (bug) from an empty list (no subscriptions).","triggerScenarios":"Calling AmazonSQSConsumerClient.SubscribeAsync(null) directly, or CAP's bootstrapper invoking SubscribeAsync with a null subscriber/topic collection when no consumers were registered but the collection itself was never initialized.","commonSituations":"Custom IConsumerClient implementations or forks of CAP where the topic collection is built from a dictionary lookup that returned null; also seen when upgrading CAP versions and the startup path changed from empty-list to null semantics.","solutions":["Pass a non-null collection; use Array.Empty<string>() or new List<string>() when there is nothing to subscribe","Verify consumers/subscribers are registered via services.AddCap(x => x.AddSubscribe(...)) before bootstrapping","Guard the call site: if (topics != null) await SubscribeAsync(topics)","Catch ArgumentNullException at startup and log which consumer client failed"],"exampleFix":"// before\nawait sqsConsumer.SubscribeAsync(GetTopics()); // GetTopics() returns null\n// after\nvar topics = GetTopics() ?? Enumerable.Empty<string>();\nawait sqsConsumer.SubscribeAsync(topics);","handlingStrategy":"validation","validationCode":"if (topics is null) throw new InvalidOperationException(\"topics must not be null; pass an empty collection for none\");","typeGuard":"bool IsValidTopics(IEnumerable<string>? t) => t is not null;","tryCatchPattern":"try { await client.SubscribeAsync(topics); } catch (ArgumentNullException ex) when (ex.ParamName == \"topics\") { logger.LogError(ex, \"SubscribeAsync received null topics\"); throw; }","preventionTips":["Always register subscribers via AddSubscribe so CAP builds the topic list","Default null topic lists to empty enumerables at the config boundary"],"tags":["dotnet","null-argument","sqs","subscription"],"backgroundTag":"null-argument","analyzedSha":"e52b8508e54cdb7a9ce7f9fec03d9ea8ad2710fb","analyzedAt":"2026-09-14T14:46:34.677Z","contentChangedAt":"2026-09-14T14:46:34.677Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}