Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.surfaces.{surface.Key}' must be a mappi
Error message
Locale '{localeCode}.surfaces.{surface.Key}' must be a mapping. What it means
Each surface value under `surfaces:` must itself be a mapping (CanonicalLocaleAuthoring.cs:117-121). A scalar or sequence (e.g. `clock: '12-hour'`) cannot describe the surface's sub-properties.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:119
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);
}
return new CanonicalLocaleDocument(
localeCode,
variantOf,
surfaces,
NormalizeCanonicalText(fileText));
}
internal static string Emit(CanonicalLocaleDocument document) => document.CanonicalText;
internal static LocaleDefinition ToLocaleDefinition(CanonicalLocaleDocument document)
{
var features = ImmutableDictionary.CreateBuilder<string, SimpleYamlValue>(StringComparer.Ordinal);View on GitHub (pinned to ffc2b77c0f)
Solutions
- Convert the surface value to a mapping, e.g. `clock:` then indented properties.
- If the surface only needs the default engine, either omit it or, for allowed paths, set `engine: "default"` inside a mapping.
- Rebuild.
Example fix
# before
surfaces:
compass: north
# after
surfaces:
compass:
full: ["north","east","south","west"] Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
if isinstance(doc.get('surfaces'), dict):
for k, v in doc['surfaces'].items():
assert isinstance(v, dict), f'surfaces.{k} 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: Writing `surfaces.clock: 'default'` or assigning a list to a surface instead of a keyed block.
Common situations: Shorthand authoring; converting a legacy scalar value into the canonical form incompletely.
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' must be a mapping.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/fbd28daf41064c0c.
Report an issue: GitHub.