Humanizr/Humanizer · error · InvalidOperationException

Unsupported number-to-words builder '{member.Builder}'.

Error message

Unsupported number-to-words builder '{member.Builder}'.

What it means

The builder dispatch switch in CreateBuilderValue handles ~40 named builders (harmony-ordinal-scale-array, billion-strategy-cardinal-scale-array, etc.). Any builder string not matching a case hits the default arm and throws. This is a generator-level configuration error indicating the contract references a builder the factory does not implement.

Source

Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/NumberToWordsEngineContractFactory.cs:536

                "scale-leading-compound-scale-array" => CreateScaleLeadingCompoundScaleArrayExpression(builderRoot),
                "scandinavian-scale-array" => CreateScaleStrategyScaleArrayExpression(builderRoot),
                "unit-leading-compound-scale-array" => CreateUnitLeadingCompoundScaleArrayExpression(builderRoot),
                "conjoined-gendered-scale-array" => CreateConjoinedGenderedScaleArrayExpression(builderRoot),
                "segmented-scale-array" => CreateSegmentedScaleArrayExpression(builderRoot),
                "stemmed-scale-array" => CreateStemmedScaleArrayExpression(builderRoot),
                "linked-vigesimal-scale-array" => CreateLinkedVigesimalScaleArrayExpression(builderRoot),
                "terminal-ordinal-scale-array" => CreateTerminalOrdinalScaleArrayExpression(builderRoot),
                "construct-state-scale-array" => CreateConstructStateScaleArrayExpression(builderRoot),
                "hyphenated-scale" => CreateHyphenatedScaleExpression(builderRoot),
                "hyphenated-scale-array" => CreateHyphenatedScaleArrayExpression(builderRoot),
                "hyphenated-ordinal-scale-array" => CreateHyphenatedOrdinalScaleArrayExpression(builderRoot),
                "dual-form-scale" => CreateDualFormScaleExpression(builderRoot),
                "macedonian-scale-array" => CreateMacedonianScaleArrayExpression(builderRoot),
                "triad-scale-array" => CreateTriadScaleArrayExpression(builderRoot),
                "gendered-scale-ordinal-array" => CreateGenderedScaleOrdinalArrayExpression(builderRoot),
                "long-scale-word-array" => CreateLongScaleWordArrayExpression(builderRoot),
                "variant-decade-scale-array" => CreateVariantDecadeScaleArrayExpression(builderRoot),
                _ => throw new InvalidOperationException($"Unsupported number-to-words builder '{member.Builder}'.")
            };
        }

        static string GetStringValue(JsonElement root, EngineContractMember member)
        {
            if (EngineContractUtilities.TryGetOptionalString(root, member.SourcePath, out var value))
            {
                return value!;
            }

            if (member.FallbackSourcePath is not null && EngineContractUtilities.TryGetOptionalString(root, member.FallbackSourcePath, out var fallback))
            {
                return fallback!;
            }

            if (member.DefaultValue is not null)
            {
                return member.DefaultValue;

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Correct the builder name to match exactly one of the supported names in the switch (check spelling, hyphens, and ordering).
  2. If the builder is new, add a case to the switch and implement the CreateXxxScaleArrayExpression method.
  3. If the builder was renamed, update the contract definition to use the current name.

Example fix

// before
new EngineContractMember(
    kind: "builder",
    sourcePath: "scales",
    builder: "billion-cardinal-scale-array",
    ...)
// after
new EngineContractMember(
    kind: "builder",
    sourcePath: "scales",
    builder: "billion-strategy-cardinal-scale-array",
    ...)
Defensive patterns

Strategy: validation

Validate before calling

// Validate all builder names are supported before generation:
static readonly HashSet<string> SupportedBuilders = new()
{
    "harmony-ordinal-scale-array","billion-strategy-cardinal-scale-array",
    /* ... all ~40 builders ... */
};
foreach (var m in contract.Members)
    if (m.Kind == "builder" && !SupportedBuilders.Contains(m.Builder))
        throw new ArgumentException($"Unsupported builder '{m.Builder}'.");

Type guard

static bool IsBuilderSupported(string builder) =>
    SupportedBuilders.Contains(builder);

Prevention

When it happens

Trigger: An EngineContractMember has a Builder value not present in the switch cases at lines 498-536. For example, a typo like 'billion-strategy-scale-array' (missing 'cardinal') or a completely new builder name without a corresponding case.

Common situations: Typo in the builder name string. Referencing a builder from an older/newer version that was renamed or removed. Adding a new builder concept without implementing its expression generator.

Related errors


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