Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.headings' must be a mapping.
Error message
Locale '{localeCode}.headings' must be a mapping. What it means
The 'headings' feature groups calendar heading sequences (month/day names) under 'full' and 'short' sub-keys, so it must be a YAML mapping. A scalar or sequence value has no named sub-properties and is rejected.
Source
Thrown at src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs:787
return !features.TryGetValue("phrases", out var phraseValue)
? null
: phraseValue is SimpleYamlMapping mapping
? LocalePhraseNormalization.Create(localeCode, mapping, preserveDurationCaseForms)
: throw new InvalidOperationException($"Locale '{localeCode}.phrases' must be a mapping.");
}
static HeadingSet? ResolveHeadings(
string localeCode,
ImmutableDictionary<string, SimpleYamlValue> features)
{
if (!features.TryGetValue("headings", out var headingValue))
{
return null;
}
if (headingValue is not SimpleYamlMapping mapping)
{
throw new InvalidOperationException($"Locale '{localeCode}.headings' must be a mapping.");
}
foreach (var property in mapping.Values.Keys.Where(static property => property is not ("full" or "short")))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.headings' defines unsupported property '{property}'. Supported properties: full, short.");
}
return new HeadingSet(
ParseHeadingSequence(mapping, "full", localeCode),
ParseHeadingSequence(mapping, "short", localeCode));
}
static SimpleYamlMapping? ResolveCalendar(
string localeCode,
ImmutableDictionary<string, SimpleYamlValue> features)
{
return !features.TryGetValue("calendar", out var calendarValue)View on GitHub (pinned to ffc2b77c0f)
Solutions
- Wrap the heading data in a mapping with 'full:' and 'short:' keys.
- Ensure each sub-key's value is itself a sequence of scalars.
- Use an existing locale file (e.g. 'en.yml') as a structural template.
Example fix
# before
headings:
- January
- February
# after
headings:
full:
- January
- February
short:
- Jan
- Feb Defensive patterns
Strategy: validation
Validate before calling
import yaml, pathlib
locales_dir = pathlib.Path('src/Humanizer/Locales')
for f in locales_dir.rglob('*.yml'):
data = yaml.safe_load(f.read_text())
if isinstance(data, dict) and 'headings' in data:
if not isinstance(data['headings'], dict):
print(f'{f.name}: headings must be a mapping, got {type(data["headings"]).__name__}') Prevention
- Wrap heading data under 'headings:' with 'full:' and 'short:' sub-keys.
- Use 'en.yml' as a structural template when authoring headings for the first time.
- Never place bare list items directly under 'headings:'.
When it happens
Trigger: A locale file sets 'headings:' to a scalar or to a bare sequence instead of a mapping containing 'full:' and 'short:' keys.
Common situations: Authoring heading data for the first time and omitting the wrapping mapping; indentation error causing heading sequences to attach at the wrong level.
Related errors
- Locale '{localeCode}.headings' defines unsupported property
- Phrase section '{path}' must be a mapping.
- Phrase section '{path}' defines unsupported property '{key}'
- Feature '{featureName}' in locale '{localeCode}' must be a s
- Locale '{localeCode}.grammar' must be a mapping.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/3635129b36ba259e.
Report an issue: GitHub.