dotnetcore/CAP · error · ArgumentNullException
Value cannot be null. (Parameter 'topicNames')
Error message
Value cannot be null. (Parameter 'topicNames')
What it means
FetchTopicsAsync validates its topicNames parameter and throws ArgumentNullException when a null collection is passed. The consumer client needs at least an empty enumerable to resolve SNS topic ARNs; a null reference is treated as a programming error rather than 'no topics'.
Solutions
- Ensure the IEnumerable<string> passed to FetchTopicsAsync is non-null; pass Array.Empty<string>() when there are no topics
- Check that the configuration source feeding the topic list is populated before startup
- If topics are truly optional, guard with topics ?? Enumerable.Empty<string>() before calling
- Wrap the call in ArgumentNullException handling and fail fast with a clear log message
Example fix
// before await consumerClient.FetchTopicsAsync(config.Topics); // config.Topics is null // after var topics = config.Topics ?? new List<string>(); await consumerClient.FetchTopicsAsync(topics);
Defensive patterns
Strategy: validation
Validate before calling
if (topicNames is null) throw new InvalidOperationException("topicNames must be provided (use an empty list for none)"); Type guard
bool HasTopics(IEnumerable<string>? t) => t is not null;
Try / catch
try { await client.FetchTopicsAsync(topics); } catch (ArgumentNullException ex) when (ex.ParamName == "topicNames") { logger.LogError(ex, "topicNames was null"); throw; } Prevention
- Initialize topic collections with Array.Empty<string>() instead of null
- Fail fast at configuration load time if the topic list section is missing
When it happens
Trigger: Calling AmazonSQSConsumerClient.FetchTopicsAsync(null) directly, or a CAP bootstrap path that passes a null topic-name collection into the SQS consumer during startup topic discovery.
Common situations: Building a custom consumer bootstrap on top of CAP where topics are read from configuration that was never populated (e.g. a missing config section deserialized to null) and the null collection is forwarded straight into FetchTopicsAsync.
Related errors
- Value cannot be null. (Parameter 'topics')
- Value cannot be null. (Parameter 'configure')
- Value cannot be null. (Parameter 'connectionString')
- Value cannot be null. (Parameter 'options')
- Value cannot be null. (Parameter 'options')
AI-assisted analysis of dotnetcore/CAP@e52b8508e5 (2026-09-14).
Data as JSON: /api/errors/8b77d7e9f43b8b47.
Report an issue: GitHub.
Appendix: source
Thrown at src/DotNetCore.CAP.AmazonSQS/AmazonSQSConsumerClient.cs:50
private IAmazonSQS? _sqsClient;
public AmazonSQSConsumerClient(string groupId, byte groupConcurrent, IOptions<AmazonSQSOptions> options)
{
_groupId = groupId;
_groupConcurrent = groupConcurrent;
_amazonSQSOptions = options.Value;
_semaphore = new SemaphoreSlim(groupConcurrent);
}
public Func<TransportMessage, object?, Task>? OnMessageCallback { get; set; }
public Action<LogMessageEventArgs>? OnLogCallback { get; set; }
public BrokerAddress BrokerAddress => new("aws_sqs", _queueUrl);
public async Task<ICollection<string>> FetchTopicsAsync(IEnumerable<string> topicNames)
{
if (topicNames == null) throw new ArgumentNullException(nameof(topicNames));
await ConnectAsync(true, false).ConfigureAwait(false);
var topicArns = new List<string>();
foreach (var topic in topicNames)
{
var createTopicRequest = new CreateTopicRequest(topic.NormalizeForAws());
var createTopicResponse = await _snsClient!.CreateTopicAsync(createTopicRequest).ConfigureAwait(false);
topicArns.Add(createTopicResponse.TopicArn);
}
await GenerateSqsAccessPolicyAsync(topicArns).ConfigureAwait(false);
return topicArns;
}
View on GitHub (pinned to e52b8508e5)