Humanizr/Humanizer · critical · InvalidOperationException
Locale '{localeCode}.surfaces.ordinal' defines unsupported p
Error message
Locale '{localeCode}.surfaces.ordinal' defines unsupported property '{property}'. Supported properties: numeric, date, dateOnly. What it means
Thrown by AddOrdinalFeatures when surfaces.ordinal in a locale YAML contains a property other than the three allowed keys: numeric, date, dateOnly. The ordinal surface is closed, so any extra key (e.g. legacy 'words', 'abbreviations') is rejected at build time.
Source
Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:408
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a scalar string, not a mapping or sequence.");
}
if (string.IsNullOrEmpty(scalar.Value))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a non-empty string.");
}
}
static void AddOrdinalFeatures(
string localeCode,
SimpleYamlMapping ordinalSurface,
ImmutableDictionary<string, SimpleYamlValue>.Builder features)
{
foreach (var property in ordinalSurface.Values.Keys.Where(static property => property is not ("numeric" or "date" or "dateOnly")))
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.ordinal' defines unsupported property '{property}'. Supported properties: numeric, date, dateOnly.");
}
if (ordinalSurface.TryGetValue("numeric", out var numericValue))
{
if (numericValue is not SimpleYamlMapping numericMapping)
{
throw new InvalidOperationException(
$"Locale '{localeCode}.surfaces.ordinal.numeric' must be a mapping, not a scalar or sequence.");
}
features["ordinalizer"] = numericMapping;
}
if (ordinalSurface.TryGetValue("date", out var dateValue))
{
if (dateValue is not SimpleYamlMapping dateMapping)
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Remove the unsupported property '{property}' from surfaces.ordinal.
- Map the data onto the supported keys: numeric (ordinalizer), date (dateToOrdinalWords), or dateOnly (dateOnlyToOrdinalWords).
- If a genuinely new ordinal surface is needed, extend AddOrdinalFeatures and SupportedSurfaceNames in the generator first.
Example fix
# before
ordinal:
words:
1: first
# after
ordinal:
numeric:
1: first Defensive patterns
Strategy: validation
Validate before calling
# Validate ordinal surface keys against the allow-list. $allowed = 'numeric','date','dateOnly' # Parse the locale YAML and assert every key under surfaces.ordinal is in $allowed.
Prevention
- Remember the ordinal surface is closed: numeric, date, dateOnly only.
- Map any legacy ordinal data onto these three keys.
- Extend AddOrdinalFeatures in the generator before introducing a new ordinal surface.
When it happens
Trigger: A contributor adds an unsupported key under surfaces.ordinal. The allow-list loop at CanonicalLocaleAuthoring.cs:404-409 flags the offending property and throws.
Common situations: Migrating from an older ordinal schema that used different property names; pasting ordinal config from another i18n library; adding locale-specific ordinal variants not yet supported by the schema.
Related errors
- Locale '{localeCode}.surfaces.ordinal.numeric' must be a map
- Locale '{localeCode}.surfaces.ordinal.date' must be a mappin
- Locale '{localeCode}.surfaces.ordinal.dateOnly' must be a ma
- 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/833ad2013e1a1854.
Report an issue: GitHub.