Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.headings.{key}[{index}]' must be a scal
Error message
Locale '{localeCode}.headings.{key}[{index}]' must be a scalar. What it means
Each entry in a headings sequence must be a YAML scalar (a plain or quoted string). If an entry is itself a nested mapping or sub-sequence, the parser cannot extract a string heading and rejects the specific entry by its index.
Source
Thrown at src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs:853
throw new InvalidOperationException($"Locale '{localeCode}.headings' must define '{key}'.");
}
if (headingValue is not SimpleYamlSequence sequence)
{
throw new InvalidOperationException($"Locale '{localeCode}.headings.{key}' must be a sequence.");
}
if (sequence.Items.Length != 16)
{
throw new InvalidOperationException($"Locale '{localeCode}.headings.{key}' must contain exactly 16 entries.");
}
var headings = ImmutableArray.CreateBuilder<string>(16);
for (var index = 0; index < sequence.Items.Length; index++)
{
if (sequence.Items[index] is not SimpleYamlScalar scalar)
{
throw new InvalidOperationException($"Locale '{localeCode}.headings.{key}[{index}]' must be a scalar.");
}
headings.Add(scalar.Value);
}
return headings.MoveToImmutable();
}
static T? TryResolveLocalePart<T>(
string localeCode,
ImmutableArray<Diagnostic>.Builder diagnostics,
Func<string, ImmutableDictionary<string, SimpleYamlValue>, T?> resolver,
ImmutableDictionary<string, SimpleYamlValue> features)
where T : class
{
try
{
return resolver(localeCode, features);View on GitHub (pinned to ffc2b77c0f)
Solutions
- Inspect the entry at the 0-based index named in the message and flatten it to a scalar string.
- Remove any nested key-value structure from that list item.
- Re-validate the whole sequence for similar structural issues at other indices.
Example fix
# before — entry 0 is a mapping
headings:
full:
- name: January
# after — entry 0 is a scalar
headings:
full:
- January 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 isinstance(data.get('headings'), dict):
for key in ('full', 'short'):
val = data['headings'].get(key)
if isinstance(val, list):
for i, item in enumerate(val):
if not isinstance(item, str):
print(f'{f.name}: headings.{key}[{i}] must be a scalar string, got {type(item).__name__}') Prevention
- Each entry in a headings sequence must be a plain string, not a nested key-value or sub-list.
- Avoid YAML flow-mapping syntax inside sequence items for headings.
- Run a lint that checks every headings entry is a scalar type.
When it happens
Trigger: One of the items under 'headings.full:' or 'headings.short:' is a mapping or nested list, e.g. '- full: January' instead of '- January'. The {index} placeholder identifies the offending position.
Common situations: Indentation drift causing a sub-key to attach as a list item; copy-pasting structured data into a flat string slot; leftover debugging nodes.
Related errors
- '{path}' must define scalar '{key}'.
- Phrase '{path}' must be a scalar string.
- Locale '{localeCode}.headings' must be a mapping.
- Locale '{localeCode}.headings' defines unsupported property
- Locale '{localeCode}.headings' must define '{key}'.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/9bbb1d0237ae8999.
Report an issue: GitHub.