Humanizr/Humanizer · error · InvalidOperationException

Phrase section '{path}' defines unsupported property '{key}'

Error message

Phrase section '{path}' defines unsupported property '{key}'. Supported properties: {allowedKeys}.

What it means

Thrown by RejectUnknownKeys when a phrase mapping contains a key that is not in the allowed set for that section. Each section closes its property list (e.g. dataUnits unit allows forms/default/zero/singular/dual/paucal/plural/many/symbol/template) to catch typos and schema drift. Surfaced as compiler diagnostic HSG003 (severity Error).

Source

Thrown at src/Humanizer.SourceGenerators/Common/LocalePhraseNormalization.cs:551

            return text;
        }

        static IEnumerable<string> GetPlaceholderNames(string text) =>
            PlaceholderRegex.Matches(text)
                .Cast<Match>()
                .Select(static match => match.Groups["name"].Value);

        static SimpleYamlMapping ExpectMapping(SimpleYamlValue value, string path) =>
            value as SimpleYamlMapping ??
            throw new InvalidOperationException($"Phrase section '{path}' must be a mapping.");

        static void RejectUnknownKeys(SimpleYamlMapping mapping, string path, params string[] allowedKeys)
        {
            foreach (var key in mapping.Values.Keys.Where(key => !allowedKeys.Contains(key, StringComparer.Ordinal)))
            {
                throw new InvalidOperationException(
                    $"Phrase section '{path}' defines unsupported property '{key}'. Supported properties: {string.Join(", ", allowedKeys)}.");
            }
        }
    }
}

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Read the diagnostic: it names the unsupported key and lists the supported properties for that path.
  2. Remove the unsupported key, or rename it to the correct supported one.
  3. If the value was meant for a different section, move it there.
  4. Rebuild to confirm the diagnostic clears.

Example fix

# before
dataUnits:
  byte:
    symobl: B
    forms:
      default: bytes
# after
dataUnits:
  byte:
    symbol: B
    forms:
      default: bytes
Defensive patterns

Strategy: validation

Validate before calling

# Compare the keys present in each phrase mapping against its allow-list.
# Example for dataUnits units (allowed: forms,default,zero,singular,dual,paucal,plural,many,symbol,template):
allowed=[forms default zero singular dual paucal plural many symbol template]
yq -o=json '.phrases.dataUnits | to_entries[] | .value | select(tag=="!!map") | keys | map(select(. as $k | $allowed | index($k) | not))' src/Humanizer/Locales/<code>.yml

Prevention

When it happens

Trigger: Adding an unsupported property such as 'count' to a data-unit phrase, 'name' to a forms block, or a typo like 'symobl' to any phrase mapping.

Common situations: Author invents a property not in the schema; typo in a known key; copy-paste from a different section whose keys are not valid here; leftover experimental field.

Related errors


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