Humanizr/Humanizer · error · InvalidOperationException

Missing required property '{propertyName}'.

Error message

Missing required property '{propertyName}'.

What it means

GenerationHelpers.GetRequiredString (GenerationHelpers.cs:188-189) returns a mandatory string property and throws when it is absent OR present but not a JSON string. Callers include duration-case number-detector resolution (GetDurationCaseNumberDetector reads pluralRule/resourceKeyDetector from a formatter profile). Both absence and a type mismatch (number/bool/object where a string is expected) surface as this same message.

Source

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

    static string ToEnumMemberName(string value)
    {
        var segments = value.Split(['-', '_'], StringSplitOptions.RemoveEmptyEntries);
        var builder = new StringBuilder(value.Length);

        foreach (var lower in segments.Select(static segment => segment.ToLowerInvariant()))
        {
            builder.Append(char.ToUpperInvariant(lower[0]));
            if (lower.Length > 1)
            {
                builder.Append(lower, 1, lower.Length - 1);
            }
        }

        return builder.ToString();
    }

    static string GetRequiredString(JsonElement element, string propertyName) =>
        GetOptionalString(element, propertyName) ?? throw new InvalidOperationException($"Missing required property '{propertyName}'.");

    static string? GetOptionalString(JsonElement element, string propertyName) =>
        element.TryGetProperty(propertyName, out var property) && property.ValueKind == JsonValueKind.String
            ? property.GetString()
            : null;

    static string? GetExplicitDurationCaseNumberDetector(ResolvedLocaleDefinition locale)
    {
        if (locale.Formatter is not { } formatter)
        {
            return null;
        }

        return GetOptionalString(formatter.ProfileRoot, "casePluralRule");
    }

    static string? GetDurationCaseNumberDetector(ResolvedLocaleDefinition locale)
    {

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Add the missing property as a JSON string value.
  2. If the value exists but is a number/bool, quote it so it becomes a JSON string.
  3. Verify against the contract/profile schema which fields are required strings for this generator path.

Example fix

// before
{ "pluralRule": 1 }
// after
{ "pluralRule": "one" }
Defensive patterns

Strategy: validation

Validate before calling

// Required string must exist AND be a string (C#)
static string RequireString(JsonElement el, string name) {
    if (!el.TryGetProperty(name, out var p) || p.ValueKind != JsonValueKind.String)
        throw new InvalidOperationException($"Missing/non-string required property '{name}'");
    return p.GetString()!;
}

Type guard

static bool IsStringProperty(JsonElement el, string name) =>
    el.TryGetProperty(name, out var p) && p.ValueKind == JsonValueKind.String;

Prevention

When it happens

Trigger: A JSON element used during generation is missing a required string field, or the field holds a non-string JSON value (e.g. a number or boolean).

Common situations: A formatter profile lacks pluralRule/resourceKeyDetector; a locale JSON value was changed from a quoted string to an unquoted number; a required field renamed upstream.

Related errors


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