Humanizr/Humanizer · error · InvalidOperationException
Locale YAML root must be a mapping.
Error message
Locale YAML root must be a mapping.
What it means
The locale YAML parser expects the document root to be a mapping (key-value pairs), because each locale file is a set of feature keys. If the top-level parsed node is a sequence or scalar — for instance the file starts with a list item — the root contract is violated and parsing aborts.
Source
Thrown at src/Humanizer.SourceGenerators/Common/LocaleYamlCatalog.cs:1335
{
sealed class LineInfo(int indent, string content, int lineNumber)
{
public int Indent { get; } = indent;
public string Content { get; } = content;
public int LineNumber { get; } = lineNumber;
}
public static SimpleYamlMapping Parse(string text)
{
var lines = NormalizeLines(text);
if (lines.Count == 0)
{
return new SimpleYamlMapping(ImmutableDictionary<string, SimpleYamlValue>.Empty.WithComparers(StringComparer.Ordinal));
}
var index = 0;
var value = ParseBlock(lines, ref index, 0, rejectDuplicateKeys: false);
return value is not SimpleYamlMapping mapping ? throw new InvalidOperationException("Locale YAML root must be a mapping.") : mapping;
}
static List<LineInfo> NormalizeLines(string text)
{
var result = new List<LineInfo>();
var lines = text.Split(["\r\n", "\n"], StringSplitOptions.None);
for (var lineNumber = 0; lineNumber < lines.Length; lineNumber++)
{
var rawLine = StripComment(lines[lineNumber]);
if (string.IsNullOrWhiteSpace(rawLine))
{
continue;
}
var indent = 0;
while (indent < rawLine.Length && rawLine[indent] == ' ')
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Ensure the file's top level consists of 'key: value' mapping entries (e.g. 'inherits:', 'formatter:', 'headings:').
- Remove any leading '- ' sequence items at column 0.
- Compare the file header against a known-good locale file.
Example fix
# before — root is a sequence - inherits: en - formatter: default # after — root is a mapping inherits: en formatter: default
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 not isinstance(data, dict):
print(f'{f.name}: YAML root must be a mapping, got {type(data).__name__}') Prevention
- Every locale YAML file must be a flat mapping of feature keys at the top level.
- Never start a locale file with a sequence item ('- ').
- Run a standard YAML parser as a pre-commit check to verify the root is a mapping.
When it happens
Trigger: A locale YAML file whose first non-blank, non-comment line begins with '- ' (a sequence item) or is a bare scalar, making the document root a sequence or scalar instead of a mapping.
Common situations: Accidentally prepending a list at the top of the file; truncating a file so only a fragment remains; pasting a YAML fragment that is a standalone list.
Related errors
- Unsupported indentation on line {lineNumber + 1}. Locale YAM
- Unexpected end of YAML document.
- Unexpected indentation on line {line.LineNumber}.
- Locale '{localeCode}.{path}' defines duplicate numeric minut
- Locale '{localeCode}.{path}.{key}' must be a string.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/48d787ea6b099dc9.
Report an issue: GitHub.