{"record":{"id":"d709f751af5ff34e","repo":"microsoft/aspire","slug":"aspirevalueattribute-requires-a-catalog-name","errorCode":null,"errorMessage":"AspireValueAttribute requires a catalog name.","messagePattern":"AspireValueAttribute requires a catalog name\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.TypeSystem/AttributeDataReader.cs","lineNumber":353,"sourceCode":"        }\n\n        for (var i = 0; i < data.NamedArguments.Count; i++)\n        {\n            var named = data.NamedArguments[i];\n            switch (named.MemberName)\n            {\n                case nameof(AspireValueData.Name):\n                    name = named.TypedValue.Value as string;\n                    break;\n                case nameof(AspireValueData.CatalogName):\n                    catalogName = named.TypedValue.Value as string;\n                    break;\n            }\n        }\n\n        return new AspireValueData\n        {\n            CatalogName = catalogName ?? throw new InvalidOperationException(\"AspireValueAttribute requires a catalog name.\"),\n            Name = name\n        };\n    }\n\n    private static ObsoleteData ParseObsoleteData(CustomAttributeData data)\n    {\n        string? message = null;\n        var isError = false;\n\n        if (data.ConstructorArguments.Count > 0 &&\n            data.ConstructorArguments[0].Value is string messageValue)\n        {\n            message = messageValue;\n        }\n\n        if (data.ConstructorArguments.Count > 1 &&\n            data.ConstructorArguments[1].Value is bool isErrorValue)\n        {","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.TypeSystem/AttributeDataReader.cs#L335-L371","documentation":"ParseAspireValueData reads an AspireValueAttribute's constructor/property data and throws InvalidOperationException if no catalog name was found on the attribute. An AspireValueData without a catalog is meaningless, so parsing fails.","triggerScenarios":"Applying [AspireValue] without a catalog name (or with an unreadable/omitted catalog argument) and then running the type-system attribute reader over the assembly.","commonSituations":"Hand-written attributes missing the catalog parameter; attribute constructor overloads misused; reflection unable to read the catalog argument due to signature mismatch.","solutions":["Add the required catalog name argument to the [AspireValue] attribute usage","Rebuild the annotated assembly so the attribute metadata is regenerated","Verify the attribute constructor overload used actually sets the catalog parameter"],"exampleFix":"// before\n[AspireValue(Name = \"OptionA\")]\n// after\n[AspireValue(\"MyCatalog\", \"OptionA\")]","handlingStrategy":"validation","validationCode":"// Verify attribute usage before scanning:\n// [AspireValue(\"Catalog\", \"Name\")] — ensure the catalog argument is present on every use.","typeGuard":null,"tryCatchPattern":"try { data = AttributeDataReader.ParseAspireValueData(attr); }\ncatch (InvalidOperationException ex) { diagnostics.Add(\"AspireValue attribute missing catalog name\"); }","preventionTips":["Always pass the catalog name positionally to [AspireValue]","Add an analyzer/CI check that scans attribute usages for missing catalog arguments"],"tags":["attributes","reflection","metadata"],"backgroundTag":"missing-required-argument","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"}