{"record":{"id":"5508ee77b352f4a1","repo":"microsoft/aspire","slug":"resource-view-limit-of-telemetryrepositorylimits-5508ee","errorCode":null,"errorMessage":"Resource view limit of {TelemetryRepositoryLimits.MaxResourceViewCount} reached.","messagePattern":"Resource view limit of (.+?) reached\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Caching.cs","lineNumber":149,"sourceCode":"                          WHERE a.resource_view_id = v.resource_view_id\n                            AND a.ordinal = {index}\n                            AND a.attribute_key = @PropertyKey{index}\n                            AND a.attribute_value = @PropertyValue{index}\n                      )\n                    \"\"\");\n            }\n            sql.Append(\" LIMIT 1;\");\n\n            var resourceViewId = connection.QuerySingleOrDefault<long?>(sql.ToString(), parameters, transaction);\n            if (resourceViewId is null)\n            {\n                var resourceViewCount = connection.QuerySingle<int>(\n                    \"SELECT COUNT(*) FROM telemetry_resource_views WHERE resource_id = @ResourceId;\",\n                    new { resource.ResourceId },\n                    transaction);\n                if (resourceViewCount >= TelemetryRepositoryLimits.MaxResourceViewCount)\n                {\n                    throw new InvalidOperationException($\"Resource view limit of {TelemetryRepositoryLimits.MaxResourceViewCount} reached.\");\n                }\n\n                resourceViewId = connection.QuerySingle<long>(\"\"\"\n                    INSERT INTO telemetry_resource_views (resource_id)\n                    VALUES (@ResourceId)\n                    RETURNING resource_view_id;\n                    \"\"\", new { resource.ResourceId }, transaction);\n                var properties = incomingView.Properties\n                    .Select((property, ordinal) => (Ordinal: ordinal, property.Key, property.Value))\n                    .ToArray();\n                SqliteBatchInsert.BatchInsertRows(\n                    connection,\n                    transaction,\n                    properties,\n                    MaxMetadataAttributeBatchSize,\n                    \"telemetry_resource_view_attributes\",\n                    [\"resource_view_id\", \"ordinal\", \"attribute_key\", \"attribute_value\"],\n                    (property, parameters) =>","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Caching.cs#L131-L167","documentation":"The SQLite telemetry repository enforces TelemetryRepositoryLimits.MaxResourceViewCount on the number of resource-view rows stored per resource in telemetry_resource_views. GetOrAddCachedResourceView throws this InvalidOperationException when a new view would exceed the per-resource limit. Views represent distinct attribute-projection combinations for a resource; the cap prevents unbounded growth per resource.","triggerScenarios":"GetOrAddCachedResourceView throws when SELECT COUNT(*) FROM telemetry_resource_views WHERE resource_id = @ResourceId >= MaxResourceViewCount and a new view combination for that resource is inserted (path shared by GetOrAddCachedResource, cachedView, and AddMetricsToDatabaseAsync). Triggered when one resource accumulates too many distinct view property sets.","commonSituations":"A single resource whose attributes keep changing during its lifetime, generating new views on each change; long-running Dashboard sessions aggregating many telemetry shapes for one service; high-cardinality attributes leaking into resource metadata.","solutions":["Keep resource attributes stable per process so a resource maps to a single view.","Reduce distinct view property combinations requested/derived for a resource.","Restart the Dashboard session (clearing cached state) if the limit was reached through many legitimate one-off views."],"exampleFix":"// before: mutating resource metadata over time\nresource.Attributes.Add($\"state.{DateTime.UtcNow}\", state);\n// after: fixed attribute set for the resource lifetime\nresource.Attributes.Add(\"service.version\", serviceVersion);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var viewId = GetOrAddCachedResourceView(connection, tx, resource, incoming);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Resource view limit\"))\n{\n    logger.LogWarning(ex, \"View limit reached for resource {Id}; new view skipped.\", resource.ResourceId);\n}","preventionTips":["Emit one fixed set of resource attributes per process.","Avoid attribute churn that creates new view combinations over a session.","Track view growth for long-running Dashboard instances."],"tags":["opentelemetry","limits","sqlite","resource-view","dashboard"],"backgroundTag":"resource-limit-exceeded","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}