Humanizr/Humanizer · error · InvalidOperationException
Unexpected east-asian scale builder.
Error message
Unexpected east-asian scale builder.
What it means
The builder name 'east-asian-scale-array' is explicitly registered as a throw in the builder switch. This is an intentional guard: east-asian scale words are handled exclusively by the AddEngineMetricScaleWords path for the 'east-asian-grouped' engine, not through the generic builder pipeline. If a contract member references this builder, it signals a misconfiguration.
Source
Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/NumberToWordsEngineContractFactory.cs:510
? root
: EngineContractUtilities.GetRequiredElement(root, member.SourcePath);
// Builders exist for repeated structured rows such as scale tables, suffix rules, and
// gender-ending records. Keeping these explicit makes the generated output easier to
// audit than trying to encode a second generic mini-language for nested collections.
return member.Builder switch
{
"harmony-ordinal-scale-array" => CreateHarmonyOrdinalScaleArrayExpression(builderRoot),
"billion-strategy-cardinal-scale-array" => CreateBillionStrategyCardinalScaleArrayExpression(builderRoot),
"contracted-one-scale-array" => CreateContractedOneScaleArrayExpression(builderRoot),
"linking-scale-array" => CreateLinkingScaleArrayExpression(builderRoot),
"linking-suffix-rule-array" => CreateLinkingSuffixRuleArrayExpression(builderRoot),
"agglutinative-ordinal-scale-array" => CreateAgglutinativeOrdinalScaleArrayExpression(builderRoot),
"contextual-decimal-scale-array" => CreateContextualDecimalScaleArrayExpression(builderRoot),
"conjunctional-scale-array" => CreateConjunctionalScaleArrayExpression(builderRoot),
"joined-scale-array" => CreateJoinedScaleArrayExpression(builderRoot),
"west-slavic-scale-forms" => CreateWestSlavicScaleFormsExpression(builderRoot),
"east-asian-scale-array" => throw new InvalidOperationException("Unexpected east-asian scale builder."),
"east-slavic-scale-array" => CreateEastSlavicScaleArrayExpression(builderRoot),
"east-slavic-gender-ending" => CreateEastSlavicGenderEndingExpression(builderRoot),
"pluralized-scale-array" => CreatePluralizedScaleArrayExpression(builderRoot),
"ordinal-prefix-scale-array" => CreateOrdinalPrefixScaleArrayExpression(builderRoot),
"inverted-tens-scale-array" => CreateInvertedTensScaleArrayExpression(builderRoot),
"indian-scale-form-array" => CreateIndianScaleFormArrayExpression(builderRoot),
"south-slavic-scale-array" => CreateSouthSlavicScaleArrayExpression(builderRoot),
"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),View on GitHub (pinned to ffc2b77c0f)
Solutions
- Remove the 'east-asian-scale-array' builder from the contract member — east-asian scales are auto-projected by the 'east-asian-grouped' engine in AddEngineMetricScaleWords.
- If the locale uses the 'east-asian-grouped' engine, ensure its scale words are defined via smallUnitWords and largeUnits in the YAML, not through a builder contract.
- If you need a different scale builder, choose one from the supported list (e.g., 'hyphenated-scale-array', 'segmented-scale-array').
Example fix
// before
new EngineContractMember(
kind: "builder",
sourcePath: "scales",
builder: "east-asian-scale-array",
...)
// after — remove this member; east-asian-grouped engine handles scales directly
// (delete the EngineContractMember entirely from the contract's Members array) Defensive patterns
Strategy: validation
Validate before calling
// Validate that no contract member uses the guarded east-asian-scale-array builder:
foreach (var m in contract.Members)
if (m.Builder == "east-asian-scale-array")
throw new ArgumentException(
"east-asian-scale-array is engine-internal; use the east-asian-grouped engine path instead."); Type guard
static bool IsBuilderAllowed(EngineContractMember m) =>
m.Builder != "east-asian-scale-array"; Prevention
- Never use 'east-asian-scale-array' as a builder name in contract definitions.
- Understand that east-asian scale words are projected by AddEngineMetricScaleWords for the 'east-asian-grouped' engine.
- Document builder names that are engine-internal vs. contract-facing in the source generator docs.
When it happens
Trigger: An EngineContractMember is constructed with builder='east-asian-scale-array' and the builder dispatch reaches line 510. The switch arm unconditionally throws InvalidOperationException. This indicates the builder was referenced from a contract definition where it should never appear.
Common situations: Copy-pasting builder names from a reference list without checking which are engine-internal. Attempting to use east-asian scale words through a builder contract instead of the dedicated engine path. Misunderstanding the east-asian-grouped engine architecture.
Related errors
- Builder members require a builder name.
- Unsupported number-to-words builder '{member.Builder}'.
- Unsupported number-to-words contract member kind '{member.Ki
- Enum members require an enum type.
- Array-backed metric scale word contracts require a value pro
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/908f1d643aff6295.
Report an issue: GitHub.