Humanizr/Humanizer · error · InvalidOperationException

Property '{propertyName}' must be a string, array, or mappin

Error message

Property '{propertyName}' must be a string, array, or mapping (got {property.ValueKind}).

What it means

Thrown by CreateUnitLeadingCompoundOrdinalPairExpression when an ordinalSingular or ordinalPlural property has an unsupported JSON value kind (not string, array, or object). The generator supports three shapes for an ordinal pair but rejects booleans, numbers, or null, because it cannot map them to the two-element string[] output.

Source

Thrown at src/Humanizer.SourceGenerators/Common/GenerationHelpers.cs:1015

            RequiredInt64Value("value"),
            BooleanValue("addSpaceBeforeNextPart"),
            OptionalEnumValue("countGender", "GrammaticalGender", "masculine"),
            RequiredStringValue("singularCardinal"),
            RequiredStringValue("pluralCardinalFormat"),
            static element => CreateUnitLeadingCompoundOrdinalPairExpression(element, "ordinalSingular"),
            static element => CreateUnitLeadingCompoundOrdinalPairExpression(element, "ordinalPlural"),
            OptionalStringValue("countWordFormNextWord"));

    static string CreateUnitLeadingCompoundOrdinalPairExpression(JsonElement element, string propertyName)
    {
        return !element.TryGetProperty(propertyName, out var property)
            ? throw new InvalidOperationException($"Missing required property '{propertyName}'.")
            : property.ValueKind switch
            {
                JsonValueKind.String => "new string[] { " + QuoteLiteral(property.GetString()!) + ", " + QuoteLiteral(property.GetString()!) + " }",
                JsonValueKind.Array => CreateStringArrayExpression(property),
                JsonValueKind.Object => CreateTerminalContinuingStringArrayExpression(property, propertyName),
                _ => throw new InvalidOperationException($"Property '{propertyName}' must be a string, array, or mapping (got {property.ValueKind}).")
            };
    }

    static string CreateTerminalContinuingStringArrayExpression(JsonElement objectElement, string propertyName)
    {
        return objectElement.ValueKind != JsonValueKind.Object
            ? throw new InvalidOperationException($"Property '{propertyName}' must be a mapping.")
            : "new string[] { " +
               QuoteLiteral(GetRequiredString(objectElement, "terminal")) + ", " +
               QuoteLiteral(GetRequiredString(objectElement, "continuing")) +
               " }";
    }

    static string CreateConjoinedGenderedScaleArrayExpression(JsonElement arrayElement)
        => CreateTypedConstructorArrayExpression(
            "ConjoinedGenderedScale",
            arrayElement,
            RequiredInt64Value("divisor"),

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Open the locale YAML and change the flagged ordinalSingular/ordinalPlural value to a quoted string, a sequence of strings, or a mapping with 'terminal' and 'continuing'.
  2. If the word looks numeric, wrap it in quotes (e.g. 'ordinalSingular: "21"') so YAML treats it as a string.
  3. Rebuild to confirm the generator accepts the corrected shape.

Example fix

# before
ordinalSingular: 21
# after
ordinalSingular: 'dwudziesty pierwszy'
Defensive patterns

Strategy: validation

Validate before calling

# Ensure ordinal pair values are quoted strings, sequences, or mappings:
#   rg "ordinalSingular:|ordinalPlural:" src/Humanizer/Locales/<code>.yml
# No value should be a bare number, boolean, or null.

Prevention

When it happens

Trigger: A locale YAML provides an ordinalSingular or ordinalPlural entry whose YAML value parses to a JSON number, boolean, or null rather than a scalar/sequence/mapping. The switch expression falls through to the default arm and throws, naming the property and the offending ValueKind.

Common situations: A contributor writes 'ordinalSingular: true' or 'ordinalSingular: 21' by mistake, or leaves a bare null. Less commonly, a YAML quoting slip turns a word into a number. Surfaces at build time via the source generator.

Related errors


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