Humanizr/Humanizer · error · InvalidOperationException
Case overlay '{path}.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.
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)
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 '{path}.phrase' must explicitly define singular
- Case overlay '{path}' must explicitly define numeric multipl
- '{path}' must define exactly one of phrase, sameRenderedAs,
- Duration case phrases use unsupported plural rule '{pluralRu
- Case-aware citation phrases for '{catalog.LocaleCode}' requi
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/da0388e7944e384e.
Report an issue: GitHub.