OrchardCMS/OrchardCore · error · ArgumentException

PluralForms array can't be empty, it must contain at least…

Error message

PluralForms array can't be empty, it must contain at least one element. If you don't want to specify the plural text, use IStringLocalizer without Plural extension.

What it means

The HTML localizer Plural extension requires at least one plural form string to derive the resource name and forms list. Passing an empty array gives the localizer nothing to look up, so the extension validates length > 0 and throws ArgumentException pointing at pluralForms, hinting that the non-array IStringLocalizer Plural should be used instead.

Solutions

  1. Ensure the pluralForms array has at least one entry before calling; the first element is used as the resource name.
  2. If you only have a count and default text, use the string/array-literal overloads of Plural or IStringLocalizer's plural extension instead of an empty array.
  3. Guard the caller: if forms.Length == 0, fall back to localizer[defaultText, count].

Example fix

// before
var html = localizer.Plural(count, Array.Empty<string>());
// after
var html = localizer.Plural(count, new[] { "{0} item", "{0} items" });
Defensive patterns

Strategy: validation

Validate before calling

if (pluralForms is null || pluralForms.Length == 0)
    return localizer[defaultText, count]; // fallback before calling Plural

Type guard

bool HasPluralForms(string[]? forms) => forms is { Length: > 0 };

Try / catch

try { html = localizer.Plural(count, forms); }
catch (ArgumentException ex) when (ex.ParamName == nameof(forms)) { html = localizer[defaultText, count]; }

Prevention

When it happens

Trigger: Calling localizer.Plural(count, new string[0]) or Plural(count, forms) where forms was built dynamically and ended up empty — checked right after ArgumentNullException.ThrowIfNull in the extension.

Common situations: Constructing plural forms from configuration or database rows that returned no rows, over-nullable refactoring producing empty arrays, or misusing the API when only a count and default text are available.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/1542cc2fbf8235e9. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Localization.Abstractions/Extensions/HtmlLocalizerExtensions.cs:38

        ArgumentNullException.ThrowIfNull(plural);

        return localizer[singular, new PluralizationArgument { Count = count, Forms = [singular, plural], Arguments = arguments }];
    }

    /// <summary>
    /// Gets the pluralization form.
    /// </summary>
    /// <param name="localizer">The <see cref="IHtmlLocalizer"/>.</param>
    /// <param name="count">The number to be used for selecting the pluralization form.</param>
    /// <param name="pluralForms">A list of pluralization forms.</param>
    /// <param name="arguments">The parameters used in the key.</param>
    public static LocalizedHtmlString Plural(this IHtmlLocalizer localizer, int count, string[] pluralForms, params object[] arguments)
    {
        ArgumentNullException.ThrowIfNull(pluralForms);

        if (pluralForms.Length == 0)
        {
            throw new ArgumentException("PluralForms array can't be empty, it must contain at least one element. If you don't want to specify the plural text, use IStringLocalizer without Plural extension.", nameof(pluralForms));
        }

        var name = pluralForms[0];

        return localizer[name, new PluralizationArgument { Count = count, Forms = pluralForms, Arguments = arguments }];
    }
}

View on GitHub (pinned to 4306c0717f)