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

  1. Remove the unsupported property '{property}' from surfaces.ordinal.
  2. Map the data onto the supported keys: numeric (ordinalizer), date (dateToOrdinalWords), or dateOnly (dateOnlyToOrdinalWords).
  3. 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

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


AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13). Data as JSON: /api/errors/833ad2013e1a1854. Report an issue: GitHub.