{"record":{"id":"f7d0e2d2580faeb0","repo":"dotnet/yarp","slug":"a-consumer-may-not-be-null","errorCode":null,"errorMessage":"A consumer may not be null","messagePattern":"A consumer may not be null","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/TelemetryConsumption/EventListenerService.cs","lineNumber":50,"sourceCode":"    private readonly object _syncObject = new();\n    private readonly bool _initialized;\n\n    public EventListenerService(\n        ILogger<TService> logger,\n        IEnumerable<TTelemetryConsumer> telemetryConsumers,\n        IEnumerable<IMetricsConsumer<TMetrics>> metricsConsumers)\n    {\n        ArgumentNullException.ThrowIfNull(logger);\n        ArgumentNullException.ThrowIfNull(telemetryConsumers);\n        ArgumentNullException.ThrowIfNull(metricsConsumers);\n\n        _logger = logger;\n        _telemetryConsumers = telemetryConsumers.ToArray();\n        _metricsConsumers = metricsConsumers.ToArray();\n\n        if (_telemetryConsumers.Any(s => s is null) || metricsConsumers.Any(c => c is null))\n        {\n            throw new ArgumentException(\"A consumer may not be null\",\n                _telemetryConsumers.Any(s => s is null) ? nameof(telemetryConsumers) : nameof(metricsConsumers));\n        }\n\n        if (_telemetryConsumers.Length == 0)\n        {\n            _telemetryConsumers = null;\n        }\n\n        if (_metricsConsumers.Length == 0)\n        {\n            _metricsConsumers = null;\n        }\n\n        lock (_syncObject)\n        {\n            if (_eventSource is EventSource eventSource)\n            {\n                EnableEventSource(eventSource);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/TelemetryConsumption/EventListenerService.cs#L32-L68","documentation":"EventListenerService (the telemetry-consumption event listener) rejects any null element inside the telemetry or metrics consumer enumerables passed to its constructor. After copying the sequences to arrays it scans for nulls and throws ArgumentException, naming whichever collection (telemetryConsumers or metricsConsumers) contained the null. This protects the listener loop, which would otherwise NullReferenceException on each event.","triggerScenarios":"Registering a consumer via AddTelemetryConsumer/AddMetricsConsumer (or direct DI) whose factory resolves to null, e.g. services.AddSingleton<ITelemetryConsumer<...>>(_ => null), or passing a params/array that contains a null entry. The null propagates into the EventListenerService constructor and trips the check.","commonSituations":"A DI factory returning null under a feature flag; a conditional AddSingleton that was meant to skip registration but instead registers null; manually building the consumer list and including an unset variable; a broken mock in tests registering null.","solutions":["Ensure every registered consumer factory returns a non-null instance; use null-conditional registration or guard the factory.","Filter nulls out of any manually constructed consumer collection before registering.","If a consumer is optional, register nothing rather than registering null.","In tests, replace null consumer stubs with real no-op implementations."],"exampleFix":"// before\nservices.AddSingleton<ITelemetryConsumer<HttpRequestTelemetry>>(_ => enabled ? new MyConsumer() : null);\n\n// after\nif (enabled) {\n    services.AddSingleton<ITelemetryConsumer<HttpRequestTelemetry>>(new MyConsumer());\n}","handlingStrategy":"validation","validationCode":"// Filter nulls before registering consumers.\nvar consumers = new ITelemetryConsumer<HttpRequestTelemetry>[] { a, b, c }\n    .Where(c => c is not null).ToArray();\nforeach (var c in consumers)\n    services.AddSingleton(c);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never register a factory that can return null; register conditionally instead.","Add a small startup assertion that GetServices<TConsumer>() contains no nulls for each consumer interface.","In tests, substitute real no-op consumers for nulls.","Treat null registrations as bugs, not as 'disabled' flags."],"tags":["telemetry","di-registration","null-check","yarp"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}