Humanizr/Humanizer · error · InvalidOperationException
Expected JSON array.
Error message
Expected JSON array.
What it means
CreateStringArrayExpression (GenerationHelpers.cs:265-275) accepts two shapes for a string-array field: a JSON Array (plain list) or a JSON Object (sparse numeric-slot mapping). Any other top-level kind (scalar, or sometimes null) throws. This emits unitsMap/tensMap-style C# string[] arrays from locale data.
Source
Thrown at src/Humanizer.SourceGenerators/Common/GenerationHelpers.cs:274
/// <code>
/// tensMap:
/// 2: 'twenty'
/// 3: 'thirty'
/// </code>
///
/// The numeric-slot form keeps YAML readable by replacing alignment hacks such as leading
/// empty strings with explicit indices. Missing slots are emitted as empty strings.
/// </summary>
static string CreateStringArrayExpression(JsonElement arrayElement)
{
if (arrayElement.ValueKind == JsonValueKind.Object)
{
return CreateNumericSlotStringArrayExpression(arrayElement);
}
if (arrayElement.ValueKind != JsonValueKind.Array)
{
throw new InvalidOperationException("Expected JSON array.");
}
var builder = new StringBuilder("new string[] { ");
var first = true;
foreach (var item in arrayElement.EnumerateArray())
{
if (item.ValueKind != JsonValueKind.String)
{
continue;
}
if (!first)
{
builder.Append(", ");
}
builder.Append(QuoteLiteral(item.GetString()!));View on GitHub (pinned to ffc2b77c0f)
Solutions
- Provide the value as a YAML/JSON array (['zero','one',...]) or as an indexed mapping ({2: 'twenty', 3: 'thirty'}).
- Check YAML indentation so the list items nest under the key.
- Verify the contract sourcePath points at the list node, not a parent scalar.
Example fix
# before unitsMap: 'zero' # after unitsMap: - 'zero' - 'one' - 'two'
Defensive patterns
Strategy: type-guard
Validate before calling
// A string-array field must be Array or Object (C#)
if (arrayElement.ValueKind != JsonValueKind.Array && arrayElement.ValueKind != JsonValueKind.Object)
throw new InvalidOperationException("Expected JSON array or indexed object for string array"); Type guard
static bool IsStringArrayShape(JsonElement el) =>
el.ValueKind == JsonValueKind.Array || el.ValueKind == JsonValueKind.Object; Prevention
- Author list fields as YAML sequences (indented '-') or indexed mappings, never scalars.
- Check YAML indentation so items nest under the key.
- Point contract sourcePaths at the list node, not a parent scalar.
When it happens
Trigger: A field expected to be a list or indexed mapping is instead a scalar (e.g. 'unitsMap: "zero"') or null.
Common situations: A YAML list collapsed to a scalar through indentation; a value left as a placeholder string; wrong node referenced by a contract sourcePath.
Related errors
- Indexed string arrays require non-negative integer keys. Inv
- Indexed string arrays require string values. Property '{prop
- Missing required property '{sourcePath}'.
- Missing required property '{propertyName}'.
- Property '{propertyName}' must be an integer.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/9e10042b3110650d.
Report an issue: GitHub.