Humanizr/Humanizer · error · ArgumentException

Teen prefix cannot be empty.

Error message

Teen prefix cannot be empty.

What it means

LinkingAffixWordsToNumberProfile's constructor throws this ArgumentException at line 240 when teenPrefix is null or empty. The grammar relies on the teen stem to detect embedded teen compounds, so an empty prefix makes the profile structurally invalid. This is a locale-authoring/generator defect, not a runtime input error: the profile is built from locale YAML by the source generator.

Source

Thrown at src/Humanizer/Localisation/WordsToNumber/LinkingAffixWordsToNumberConverter.cs:240

sealed class LinkingAffixWordsToNumberProfile(
    FrozenDictionary<string, long> cardinalMap,
    string teenPrefix,
    long teenBaseValue,
    string[] linkedSuffixes,
    string[] ignoredTokens,
    string[] negativePrefixes,
    long hundredValue = 100,
    long scaleThreshold = 1000)
{
    /// <summary>
    /// Gets the token-to-value map used by the parser.
    /// </summary>
    public FrozenDictionary<string, long> CardinalMap { get; } = cardinalMap;
    /// <summary>
    /// Gets the prefix that marks a teen stem.
    /// </summary>
    public string TeenPrefix { get; } = string.IsNullOrEmpty(teenPrefix)
        ? throw new ArgumentException("Teen prefix cannot be empty.", nameof(teenPrefix))
        : teenPrefix;
    /// <summary>
    /// Gets the base value added when a teen prefix is matched.
    /// </summary>
    public long TeenBaseValue { get; } = teenBaseValue;
    /// <summary>
    /// Gets the suffixes that may be attached to a linked cardinal token.
    /// </summary>
    public string[] LinkedSuffixes { get; } = linkedSuffixes;
    /// <summary>
    /// Gets the tokens that should be skipped during parsing.
    /// </summary>
    public string[] IgnoredTokens { get; } = ignoredTokens;
    /// <summary>
    /// Gets the prefixes that mark a negative number phrase.
    /// </summary>
    public string[] NegativePrefixes { get; } = negativePrefixes;
    /// <summary>

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Set a non-empty teen prefix value in the locale YAML (number.words profile) for the linking-affix language.
  2. Re-run the locale source generator and the locale tests so the profile is reconstructed from fixed data.
  3. Add an authoring unit test that constructs the profile and asserts it does not throw.
  4. If you hit this as a library user, file an issue against the affected locale's data; you cannot pass input that avoids it.

Example fix

// before (locale YAML)
teenPrefix: ""
// after
teenPrefix: "decai",  // language-appropriate non-empty teen stem
Defensive patterns

Strategy: validation

Validate before calling

// Authoring-time guard: assert the locale profile builds.
// In locale tests, resolve the converter for the culture and assert no throw:
var converter = Configurator.GetWordsToNumberConverter(targetCulture);
Assert.True(converter.TryToNumber("test", out _));

Prevention

When it happens

Trigger: A locale YAML file for a linking-affix language omits or blanks the teen prefix; the source generator passes an empty teenPrefix into the profile constructor; or a contributor constructs the internal profile directly without a teen stem. The throw happens during registry/profile construction (typically at first use).

Common situations: Adding or editing a linking-affix locale and forgetting the teen prefix key; a generator/registry wiring bug; a YAML value that parses to empty after normalization.

Related errors


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