Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.surfaces' must be a mapping.
Error message
Locale '{localeCode}.surfaces' must be a mapping. What it means
`surfaces:` must be a YAML mapping (CanonicalLocaleAuthoring.cs:103-105). A scalar or sequence here cannot hold named surfaces, so the generator rejects it.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:105
var variantOf = root.GetScalar("variantOf");
SimpleYamlMapping surfaces;
if (!root.TryGetValue("surfaces", out var surfacesValue))
{
if (string.IsNullOrWhiteSpace(variantOf))
{
throw new InvalidOperationException(
$"Locale '{localeCode}' must define required top-level property 'surfaces'.");
}
surfaces = new SimpleYamlMapping(
ImmutableDictionary<string, SimpleYamlValue>.Empty.WithComparers(StringComparer.Ordinal));
}
else
{
surfaces = surfacesValue is SimpleYamlMapping surfacesMapping
? surfacesMapping
: throw new InvalidOperationException($"Locale '{localeCode}.surfaces' must be a mapping.");
}
foreach (var surface in surfaces.Values)
{
if (!SupportedSurfaceNames.Contains(surface.Key, StringComparer.Ordinal))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces' defines unsupported surface '{surface.Key}'. " +
$"Supported surfaces: {string.Join(", ", SupportedSurfaceNames)}.");
}
if (surface.Value is not SimpleYamlMapping)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.{surface.Key}' must be a mapping.");
}
RejectExplicitDefaultEngines(localeCode, $"surfaces.{surface.Key}", surface.Value);View on GitHub (pinned to ffc2b77c0f)
Solutions
- Make surfaces a mapping: `surfaces:` followed by indented `key:` blocks.
- For an empty stub use `surfaces: {}` (flow mapping).
- Re-run the build.
Example fix
# before
surfaces: clock
# after
surfaces:
clock: {} Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
if 'surfaces' in doc:
assert isinstance(doc['surfaces'], dict), 'surfaces: must be a mapping' Prevention
- Author locales against the canonical schema; the error message lists the exact allowed names.
- Run `dotnet build src/Humanizer/Humanizer.csproj` locally so the generator reports locale errors before push.
- Copy an existing compliant locale file as your template rather than writing YAML from scratch.
When it happens
Trigger: `surfaces: en` or `surfaces: [clock, number]` instead of a keyed mapping; a stray `:` placement turning it into a scalar.
Common situations: Hand-typing the surfaces line; bad copy-paste from a list.
Related errors
- Locale '{localeCode}' defines unsupported top-level property
- Locale '{localeCode}' must define required top-level propert
- Locale '{declaredLocale}' must match file locale '{localeCod
- Locale '{localeCode}' must define required top-level propert
- Locale '{localeCode}.surfaces' defines unsupported surface '
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/3e44e3b0c46b1f40.
Report an issue: GitHub.