{"record":{"id":"7cb99876db5d9f4a","repo":"microsoft/aspire","slug":"instrument-name-is-required","errorCode":null,"errorMessage":"Instrument name is required.","messagePattern":"Instrument name is required\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Caching.cs","lineNumber":271,"sourceCode":"                    cachedScope = GetOrAddCachedScope(scopeId, incomingScope.Name, incomingScope.Version, incomingScope.Attributes);\n                }\n            }\n\n            return AddCachedScope(resource, cachedScope, telemetryType);\n        }\n    }\n\n    private CachedInstrument GetOrAddCachedInstrument(\n        SqliteConnection connection,\n        IDbTransaction transaction,\n        CachedResource resource,\n        CachedResourceView resourceView,\n        CachedResourceScope resourceScope,\n        Metric metric)\n    {\n        if (string.IsNullOrEmpty(metric.Name))\n        {\n            throw new InvalidOperationException(\"Instrument name is required.\");\n        }\n\n        lock (_cacheLock)\n        {\n            if (resourceScope.Instruments.TryGetValue(metric.Name, out var instrument))\n            {\n                return instrument;\n            }\n\n            EnsureCachedInstrumentsLoaded(connection, transaction, resource, resourceScope);\n            if (resourceScope.Instruments.TryGetValue(metric.Name, out instrument))\n            {\n                return instrument;\n            }\n\n            var instrumentCount = resource.InstrumentCount ??= connection.QuerySingle<int>(\n                    \"SELECT COUNT(*) FROM telemetry_metric_instruments WHERE resource_id = @ResourceId;\",\n                    new { resource.ResourceId },","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Caching.cs#L253-L289","documentation":"Aspire Dashboard's telemetry repository caches metrics by instrument name. When an incoming OTLP metric arrives, GetOrAddCachedInstrument first asserts the metric has a non-empty Name; a metric without an instrument name cannot be keyed in the cache or stored in the database, so it throws InvalidOperationException to reject malformed ingest data.","triggerScenarios":"An OTLP ExportMetricsServiceRequest contains a metric whose Name field is null or empty; AddMetricToDatabase calls GetOrAddCachedInstrument and the string.IsNullOrEmpty(metric.Name) guard fires.","commonSituations":"A custom or misconfigured instrumentation library emits an unnamed metric; a proxy/collector strips or mangles metric names; hand-crafted OTLP protobuf payloads or tests send metrics with only display names set.","solutions":["Fix the emitter so every OTLP Metric sets Name before export (e.g. ensure the meter/instrument name is non-empty in your instrumentation library).","Inspect the sending SDK/collector configuration to find why a metric is created without a name.","If exporting hand-built protobuf, validate Name before calling Export.","Wrap dashboard ingest processing so the exception is logged with the resource/scope context instead of aborting the whole batch."],"exampleFix":"// before (client emitting unnamed metric)\nvar counter = meter.CreateCounter<long>(\"\", \"requests\");\n// after\nvar counter = meter.CreateCounter<long>(\"app.requests.count\", \"requests\");","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(metric.Name))\n{\n    // skip or fix before calling dashboard ingest\n    return;\n}","typeGuard":"static bool HasInstrumentName(OtlpCollector.Metrics.V1.Metric m) => !string.IsNullOrEmpty(m.Name);","tryCatchPattern":null,"preventionTips":["Always set a non-empty instrument name in CreateCounter/CreateHistogram calls.","Add a unit test asserting every metric your app emits has a name.","If writing custom OTLP protobuf, validate required fields before Export."],"tags":["otlp","metrics","telemetry-storage"],"backgroundTag":"empty-required-field","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}