Humanizr/Humanizer · error · InvalidOperationException

Failed to project metric scale words for locale '{locale.Loc

Error message

Failed to project metric scale words for locale '{locale.LocaleCode}' using engine '{profile.Engine}': {exception.Message}

What it means

When the source generator builds metric scale word profiles for each locale, it wraps any exception from CreateMetricScaleWords in an InvalidOperationException that includes the locale code, engine name, and original exception message. This is a context-enrichment wrapper — the inner exception carries the root cause, and this message tells you which locale and engine triggered it.

Source

Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/MetricScaleWordCatalogInput.cs:41

                            locale.LocaleCode,
                            ImmutableArray<MetricScaleWordDefinition>.Empty);
                    }

                    var profile = new NumberToWordsProfileDefinition(
                        feature.ProfileName!,
                        GetRequiredString(feature.ProfileRoot, "engine"),
                        feature.ProfileRoot);
                    try
                    {
                        return new MetricScaleWordProfileDefinition(
                            locale.LocaleCode,
                            NumberToWordsEngineContractFactory.CreateMetricScaleWords(
                                profile,
                                EngineContractCatalog.NumberToWords));
                    }
                    catch (Exception exception)
                    {
                        throw new InvalidOperationException(
                            $"Failed to project metric scale words for locale '{locale.LocaleCode}' " +
                            $"using engine '{profile.Engine}': {exception.Message}",
                            exception);
                    }
                })
                .Where(static profile => !profile.ScaleWords.IsDefaultOrEmpty)
                .ToImmutableArray();

            return new(profiles);
        }

        public void Emit(SourceProductionContext context)
        {
            var builder = new StringBuilder();
            builder.AppendLine("#nullable enable");
            builder.AppendLine("namespace Humanizer;");
            builder.AppendLine();
            builder.AppendLine("static partial class LocalizedMetricScaleWordCatalog");

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Read the full exception message including the inner exception — the root cause is in exception.Message after the colon.
  2. Fix the underlying issue in the locale YAML identified by the inner exception (e.g., missing property, unknown builder).
  3. Temporarily set the locale's numberToWords profile to not use a generated profile to isolate whether the metric scale word projection or the main profile is at fault.

Example fix

# The error message format is:
# "Failed to project metric scale words for locale 'fr' using engine 'billion-strategy': <inner>"
# Fix the <inner> cause — e.g., if inner says "Missing required string property 'millionSingularWord'":
# before (fr.yml)
numberToWords:
  engine: 'billion-strategy'
  cardinal:
    scales: [...]
# after
numberToWords:
  engine: 'billion-strategy'
  cardinal:
    millionSingularWord: 'million'
    millionPluralWord: 'millions'
    billionStrategy: 'billion-word'
    billionSingularWord: 'milliard'
    billionPluralWord: 'milliards'
Defensive patterns

Strategy: validation

Validate before calling

# Before building, validate the locale's numberToWords YAML can be projected.
# Run a dry parse that exercises CreateMetricScaleWords logic paths:
python3 -c "
import yaml, sys
for f in sys.argv[1:]:
    d = yaml.safe_load(open(f))
    n2w = d.get('numberToWords') or {}
    engine = n2w.get('engine')
    if not engine: continue
    print(f'{f}: engine={engine} — verify all required properties for this engine are present')
" src/Humanizer/Locales/*.yml

Prevention

When it happens

Trigger: Any exception thrown inside NumberToWordsEngineContractFactory.CreateMetricScaleWords for a locale that uses a generated number-to-words profile. The catch at line 39 wraps and rethrows with locale/engine context. The inner exception is typically one of errors 253-259.

Common situations: Editing a locale's numberToWords YAML block and introducing a structural error (missing property, unknown builder, bad contract member). Upgrading Humanizer and a locale's engine contract changed shape. Adding a new locale with an incomplete numberToWords section.

Related errors


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