Humanizr/Humanizer · critical · InvalidOperationException

Locale '{localeCode}.surfaces.number.formatting.{propertyNam

Error message

Locale '{localeCode}.surfaces.number.formatting.{propertyName}' must be a scalar string, not a mapping or sequence.

What it means

Thrown by ValidateOptionalFormattingProperty when a property under surfaces.number.formatting (decimalSeparator, negativeSign, or groupSeparator) is present but is not a scalar — it is a YAML mapping or sequence. These three values are single characters/strings, so structured values are rejected at build time.

Source

Thrown at src/Humanizer.SourceGenerators/Common/CanonicalLocaleAuthoring.cs:390

            ValidateOptionalFormattingProperty(localeCode, formatting, "groupSeparator");

            if (formatting.Values.Count == 0)
            {
                throw new InvalidOperationException(
                    $"Locale '{localeCode}.surfaces.number.formatting' must define at least one property.");
            }
        }

        static void ValidateOptionalFormattingProperty(string localeCode, SimpleYamlMapping formatting, string propertyName)
        {
            if (!formatting.TryGetValue(propertyName, out var value))
            {
                return;
            }

            if (value is not SimpleYamlScalar scalar)
            {
                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(

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Rewrite the property as a single inline string scalar, e.g. 'decimalSeparator: ","'.
  2. Verify YAML indentation so the value sits on the same line as the key.
  3. Rebuild to confirm ValidateOptionalFormattingProperty passes.

Example fix

# before
number:
  formatting:
    decimalSeparator:
      value: ","
# after
number:
  formatting:
    decimalSeparator: ","
Defensive patterns

Strategy: validation

Validate before calling

# Ensure formatting properties are inline scalars:
# 'decimalSeparator: ","' rather than nested mappings.
# YAML lint: each of the three keys, if present, must have a scalar value.

Prevention

When it happens

Trigger: A locale YAML writes 'decimalSeparator:\n value: ","' (nested mapping) or a list form for one of the three formatting properties. The type check at CanonicalLocaleAuthoring.cs:386-392 fails because the value is not a SimpleYamlScalar.

Common situations: Pasting CLDR nested symbol objects; mis-indenting so the value becomes a child mapping; converting from a JSON config that wrapped symbols in objects.

Related errors


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