Humanizr/Humanizer · error · InvalidOperationException

{diagnosticMessages}

Error message

{diagnosticMessages}

What it means

Thrown by LocaleCoverageInput.Create when the locale catalog produced any diagnostics while loading and resolving locale YAML files. It aggregates all diagnostic messages (sorted) into one exception so the developer sees every catalog problem at once. It is a pre-condition gate: coverage cannot be computed over an inconsistent catalog.

Source

Thrown at src/Humanizer.SourceGenerators/Common/LocaleCoverageInput.cs:44

            new("clock", "Clock notation", optional: false, ["timeOnlyToClockNotation"], static locale => locale.TimeOnlyToClockNotation is not null),
            new("compass", "Compass headings", optional: false, ["headings"], static locale => locale.Headings is not null),
            new("calendarOverride", "Calendar override", optional: true, ["calendar"], static locale => locale.Calendar is not null),
            new(
                "numberFormattingOverride",
                "Number-format override",
                optional: true,
                ["numberFormatting"],
                static locale => locale.NumberFormatting is not null)
        ];

        public ImmutableArray<LocaleCoverageCapability> Capabilities { get; } = capabilities;
        public ImmutableArray<LocaleCoverageRow> Locales { get; } = locales;

        public static LocaleCoverageInput Create(LocaleCatalogInput catalog)
        {
            if (!catalog.Diagnostics.IsEmpty)
            {
                throw new InvalidOperationException(
                    string.Join(
                        "\n",
                        catalog.Diagnostics
                            .Select(static diagnostic => diagnostic.GetMessage())
                            .OrderBy(static message => message, StringComparer.Ordinal)));
            }
            if (catalog.Locales.IsEmpty)
            {
                throw new InvalidOperationException("Locale coverage requires at least one canonical locale.");
            }

            var rows = ImmutableArray.CreateBuilder<LocaleCoverageRow>(catalog.Locales.Length);
            foreach (var locale in catalog.Locales.OrderBy(static locale => locale.LocaleCode, StringComparer.Ordinal))
            {
                var coverage = ImmutableDictionary.CreateBuilder<string, LocaleCoverageStatus>(StringComparer.Ordinal);
                foreach (var definition in Definitions)
                {
                    var resolved = definition.IsResolved(locale);

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Read the full exception message; it lists each catalog diagnostic on its own line, naming the offending locale and problem.
  2. Fix the underlying locale YAML (correct the locale code, parent reference, or required key) so the catalog loads cleanly.
  3. Rebuild; the coverage generator only runs once the catalog has zero diagnostics.
Defensive patterns

Strategy: validation

Validate before calling

# The coverage generator only runs once the locale catalog is clean.
# To preview catalog diagnostics before building, run the generator's test
# harness or a locale-catalog unit test that surfaces catalog.Diagnostics.

Prevention

When it happens

Trigger: At least one locale YAML file failed catalog validation (duplicate locale codes, unresolvable variant chains, missing required top-level keys, etc.), causing catalog.Diagnostics to be non-empty. LocaleCoverageInput.Create joins all those messages and throws.

Common situations: A contributor adds or edits a locale that introduces a catalog-level error (e.g. declares a variantOf pointing at a non-existent parent, or two files claim the same locale code). The locale-coverage generator then fails with the aggregated diagnostic text during dotnet build.

Related errors


AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13). Data as JSON: /api/errors/4e4ca69199f11cf8. Report an issue: GitHub.