Humanizr/Humanizer · error · InvalidOperationException
Locale '{localeCode}.surfaces' defines unsupported surface '
Error message
Locale '{localeCode}.surfaces' defines unsupported surface '{surface.Key}'. Supported surfaces: {string.Join(", ", SupportedSurfaceNames)}. What it means
Each key under `surfaces:` must be one of the supported surface names: list, formatter, durationCases, phrases, number, ordinal, clock, compass, calendar, inflection (CanonicalLocaleAuthoring.cs:108-115). Unknown surface keys are rejected so contributors don't add content the generator ignores.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:112
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);
}
return new CanonicalLocaleDocument(
localeCode,
variantOf,
surfaces,
NormalizeCanonicalText(fileText));View on GitHub (pinned to ffc2b77c0f)
Solutions
- Rename the key to a supported surface name from the list in the message.
- For number content use surfaces.number.words / .parse / .formatting rather than a top-level numberToWords.
- Remove the surface if it was added by mistake.
Example fix
# before
surfaces:
cloc: {}
# after
surfaces:
clock: {} Defensive patterns
Strategy: validation
Validate before calling
import yaml, sys
ALLOWED = {'list','formatter','durationCases','phrases','number','ordinal','clock','compass','calendar','inflection'}
doc = yaml.safe_load(open(sys.argv[1], encoding='utf-8'))
if isinstance(doc.get('surfaces'), dict):
bad = [k for k in doc['surfaces'] if k not in ALLOWED]
assert not bad, f'unsupported surfaces: {bad}' 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: A surface key typo (cloc, calender), or a legacy flat name placed under surfaces (e.g. surfaces.numberToWords instead of surfaces.number.words).
Common situations: Renaming/migrating a locale and putting the old property name under surfaces; spelling mistakes.
Related errors
- Locale '{localeCode}' defines unsupported top-level property
- Locale '{localeCode}.surfaces.number' defines unsupported pr
- Locale '{localeCode}' must define required top-level propert
- Locale '{declaredLocale}' must match file locale '{localeCod
- Locale '{localeCode}' must define required top-level propert
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/fe984e350fb79227.
Report an issue: GitHub.