Humanizr/Humanizer · critical · InvalidOperationException
Locale '{localeCode}.surfaces.calendar.months' items must be
Error message
Locale '{localeCode}.surfaces.calendar.months' items must be scalar strings. What it means
Thrown by AddCalendarFeatures when surfaces.calendar.months is a 12-element sequence but one or more items is not a YAML scalar string (e.g. a nested mapping or sequence). Month names must be plain strings so they can be emitted directly into the generated calendar table.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:468
{
foreach (var property in calendarSurface.Values.Keys.Where(static property => property is not ("months" or "monthsGenitive" or "hijriMonths")))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.calendar' defines unsupported property '{property}'. Supported properties: months, monthsGenitive, hijriMonths.");
}
var hasMonths = calendarSurface.TryGetValue("months", out var monthsValue);
if (hasMonths)
{
if (monthsValue is not SimpleYamlSequence monthsSeq || monthsSeq.Items.Length != 12)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.calendar.months' must be a sequence of exactly 12 strings.");
}
if (monthsSeq.Items.Any(static item => item is not SimpleYamlScalar))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.calendar.months' items must be scalar strings.");
}
}
if (calendarSurface.TryGetValue("monthsGenitive", out var monthsGenitiveValue))
{
if (!hasMonths)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.calendar.monthsGenitive' requires 'months' to also be present.");
}
if (monthsGenitiveValue is not SimpleYamlSequence genitiveSeq || genitiveSeq.Items.Length != 12)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.calendar.monthsGenitive' must be a sequence of exactly 12 strings.");
}
View on GitHub (pinned to ffc2b77c0f)
Solutions
- Flatten every month entry to a plain scalar string in the sequence.
- Verify each list item is '- Janvier' style (or inline '[Janvier, ...]'), not a nested block.
- Rebuild to confirm the scalar-items check passes.
Example fix
# before
calendar:
months:
- name: Janvier
- name: Février
# after
calendar:
months: [Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre] Defensive patterns
Strategy: validation
Validate before calling
# Ensure every months item is a scalar string, not a nested object.
# After parsing, assert: $months | ForEach-Object { $_ -is [string] }. Prevention
- Flatten month entries to plain strings; do not wrap names in objects.
- Prefer inline sequence form '[A, B, ...]' to avoid indentation-induced mappings.
- Build after edits to surface the offending item.
When it happens
Trigger: A month entry is written as a nested object (e.g. '- {name: Janvier}') or a sub-list. The check monthsSeq.Items.Any(item => item is not SimpleYamlScalar) at CanonicalLocaleAuthoring.cs:466-470 fires.
Common situations: Pasting CLDR month objects that wrap the name in metadata; mis-indenting list items so they become mappings; converting from a structured calendar format.
Related errors
- Locale '{localeCode}.surfaces.calendar' defines unsupported
- Locale '{localeCode}.surfaces.calendar.months' must be a seq
- Locale '{localeCode}.surfaces.calendar.monthsGenitive' requi
- Locale '{localeCode}.surfaces.calendar.monthsGenitive' must
- Locale '{localeCode}.surfaces.calendar.monthsGenitive' items
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/d4f9c7519db2b022.
Report an issue: GitHub.