microsoft/aspire · error · InvalidOperationException

AspireValueAttribute requires a catalog name.

Error message

AspireValueAttribute requires a catalog name.

What it means

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.

Solutions

  1. Add the required catalog name argument to the [AspireValue] attribute usage
  2. Rebuild the annotated assembly so the attribute metadata is regenerated
  3. Verify the attribute constructor overload used actually sets the catalog parameter

Example fix

// before
[AspireValue(Name = "OptionA")]
// after
[AspireValue("MyCatalog", "OptionA")]
Defensive patterns

Strategy: validation

Validate before calling

// Verify attribute usage before scanning:
// [AspireValue("Catalog", "Name")] — ensure the catalog argument is present on every use.

Try / catch

try { data = AttributeDataReader.ParseAspireValueData(attr); }
catch (InvalidOperationException ex) { diagnostics.Add("AspireValue attribute missing catalog name"); }

Prevention

When it happens

Trigger: Applying [AspireValue] without a catalog name (or with an unreadable/omitted catalog argument) and then running the type-system attribute reader over the assembly.

Common situations: Hand-written attributes missing the catalog parameter; attribute constructor overloads misused; reflection unable to read the catalog argument due to signature mismatch.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/d709f751af5ff34e. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.TypeSystem/AttributeDataReader.cs:353

        }

        for (var i = 0; i < data.NamedArguments.Count; i++)
        {
            var named = data.NamedArguments[i];
            switch (named.MemberName)
            {
                case nameof(AspireValueData.Name):
                    name = named.TypedValue.Value as string;
                    break;
                case nameof(AspireValueData.CatalogName):
                    catalogName = named.TypedValue.Value as string;
                    break;
            }
        }

        return new AspireValueData
        {
            CatalogName = catalogName ?? throw new InvalidOperationException("AspireValueAttribute requires a catalog name."),
            Name = name
        };
    }

    private static ObsoleteData ParseObsoleteData(CustomAttributeData data)
    {
        string? message = null;
        var isError = false;

        if (data.ConstructorArguments.Count > 0 &&
            data.ConstructorArguments[0].Value is string messageValue)
        {
            message = messageValue;
        }

        if (data.ConstructorArguments.Count > 1 &&
            data.ConstructorArguments[1].Value is bool isErrorValue)
        {

View on GitHub (pinned to 25830f84bd)