Humanizr/Humanizer · error · InvalidOperationException

Indexed string arrays require string values. Property '{prop

Error message

Indexed string arrays require string values. Property '{property.Name}' was {property.Value.ValueKind}.

What it means

In the same indexed-mapping path, CreateNumericSlotStringArrayExpression (GenerationHelpers.cs:315-318) requires each value to be a JSON string. A number, boolean, object, or array value fails the ValueKind check; the message reports the actual ValueKind to aid diagnosis.

Source

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

    static string CreateNumericSlotStringArrayExpression(JsonElement objectElement)
    {
        if (!objectElement.EnumerateObject().Any())
        {
            return "Array.Empty<string>()";
        }

        var indexedValues = new SortedDictionary<int, string>();
        foreach (var property in objectElement.EnumerateObject())
        {
            if (!int.TryParse(property.Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out var index) || index < 0)
            {
                throw new InvalidOperationException($"Indexed string arrays require non-negative integer keys. Invalid key '{property.Name}'.");
            }

            if (property.Value.ValueKind != JsonValueKind.String)
            {
                throw new InvalidOperationException($"Indexed string arrays require string values. Property '{property.Name}' was {property.Value.ValueKind}.");
            }

            indexedValues[index] = property.Value.GetString()!;
        }

        var builder = new StringBuilder("new string[] { ");
        var first = true;
        var lastIndex = indexedValues.Keys.Max();

        for (var index = 0; index <= lastIndex; index++)
        {
            if (!first)
            {
                builder.Append(", ");
            }

            builder.Append(QuoteLiteral(indexedValues.TryGetValue(index, out var value) ? value : string.Empty));
            first = false;

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Quote the value so it is a string: 2: 'twenty'.
  2. Replace any null/bool/object placeholder with the intended text.
  3. Run a YAML linter that flags unquoted scalars in string-typed mappings.

Example fix

# before
tensMap:
  2: 20
  3: 30
# after
tensMap:
  2: 'twenty'
  3: 'thirty'
Defensive patterns

Strategy: validation

Validate before calling

// Indexed string-array values must be strings (C#)
foreach (var prop in obj.EnumerateObject())
    if (prop.Value.ValueKind != JsonValueKind.String)
        throw new InvalidOperationException($"Index '{prop.Name}' value must be a string, was {prop.Value.ValueKind}");

Type guard

static bool AllStringValues(JsonElement obj) =>
    obj.EnumerateObject().All(p => p.Value.ValueKind == JsonValueKind.String);

Prevention

When it happens

Trigger: An indexed string-array mapping has a non-string value, e.g. {2: 20} (number) instead of {2: 'twenty'} (string).

Common situations: Unquoted numeric value that YAML parses as a number; boolean or null placeholder left in place of a real string.

Related errors


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