Humanizr/Humanizer · error · InvalidOperationException
Case overlay ' .multiple.forms' must explicitly define…
Error message
Case overlay '{path}.multiple.forms' must explicitly define reachable '{requiredForm}' form. What it means
Thrown by ValidateReachableMultipleForms after confirming a 'multiple' key exists, when the locale's plural rule requires a specific named form (e.g. 'dual', 'paucal', 'plural') that is not present in the multiple.forms mapping. The validator iterates the requiredMultipleForms array and throws on the first missing form.
Solutions
- Look up the required forms for the locale's plural rule in GetRequiredMultipleForms (e.g. arabic-cardinal needs default, zero, dual, plural, many).
- Add the missing named form(s) to the 'multiple.forms' mapping at the reported path.
- Ensure 'forms' is a mapping (keyed by form name) and not a scalar string unless only 'default' is required.
- Rebuild to confirm all required forms are reachable.
Example fix
# before (slovenian locale; missing 'dual' and 'paucal')
second:
phrase:
multiple:
forms:
default: sekund
# after
second:
phrase:
multiple:
forms:
default: sekund
dual: sekundi
paucal: sekunde Defensive patterns
Strategy: validation
Validate before calling
# Map plural rule to required forms and verify each phrase has them
$ruleMap = @{
'singular-plural' = @('default','plural')
'arabic-like' = @('default','dual','plural')
'arabic-cardinal' = @('default','zero','dual','plural','many')
'polish' = @('default','paucal')
'slovenian' = @('default','dual','paucal')
}
# For each phrase, check that multiple.forms contains all required form names Prevention
- Look up the required forms for the locale's plural rule in the GetRequiredMultipleForms switch table.
- Ensure 'multiple.forms' is a mapping keyed by form name, not a scalar.
- Add a unit test that exercises the locale's duration output for cardinal numbers covering all plural categories.
When it happens
Trigger: The phrase defines a 'multiple.forms' mapping but omits a form that GetRequiredMultipleForms mandates for the locale's plural rule. For example, an 'arabic-like' locale missing 'dual', or a 'slovenian' locale missing 'paucal'.
Common situations: A contributor copies a phrase from a singular-plural locale into an Arabic-like or Slavic locale without adding the extra plural categories. Also occurs when the 'forms' sub-key is a scalar (string) instead of a mapping, leaving all named forms unreachable.
Related errors
- Case overlay ' ' must explicitly define numeric multiple…
- Case overlay ' .phrase' must explicitly define singular and…
- Case-aware citation phrases for
- Case-aware citation phrases for
- Case-aware citation phrases for
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/da0388e7944e384e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs:884
if (multiple.TryGetValue("forms", out var formsValue))
{
hasScalarDefault = formsValue is SimpleYamlScalar;
forms = formsValue as SimpleYamlMapping;
}
else
{
forms = multiple;
}
foreach (var requiredForm in requiredMultipleForms)
{
if ((requiredForm == "default" && hasScalarDefault) ||
forms?.TryGetValue(requiredForm, out _) == true)
{
continue;
}
throw new InvalidOperationException(
$"Case overlay '{path}.multiple.forms' must explicitly define reachable '{requiredForm}' form.");
}
}
static void ValidateCitationBaseDurationForms(
DurationCaseCatalog catalog,
SimpleYamlValue? phrasesValue,
ImmutableArray<string> requiredMultipleForms)
{
if (!catalog.Realizations.TryGetValue(catalog.CitationCase, out var citation) ||
citation.Kind != DurationCaseRealizationKind.Authored ||
citation.Units.Count != 0)
{
return;
}
var path = $"{catalog.LocaleCode}.phrases.duration";
var phrases = phrasesValue is nullView on GitHub (pinned to ffc2b77c0f)