{"record":{"id":"6cf648d17d762a00","repo":"Humanizr/Humanizer","slug":"input-words-cannot-be-empty-6cf648","errorCode":null,"errorMessage":"Input words cannot be empty.","messagePattern":"Input words cannot be empty\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/WordsToNumber/LinkingAffixWordsToNumberConverter.cs","lineNumber":31,"sourceCode":"    {\n        if (!TryConvert(words, out var parsedValue, out var unrecognizedWord))\n        {\n            throw new ArgumentException($\"Unrecognized number word: {unrecognizedWord}\");\n        }\n\n        return parsedValue;\n    }\n\n    /// <inheritdoc />\n    public override bool TryConvert(string words, out long parsedValue) =>\n        TryConvert(words, out parsedValue, out _);\n\n    /// <inheritdoc />\n    public override bool TryConvert(string words, out long parsedValue, out string? unrecognizedWord)\n    {\n        if (string.IsNullOrWhiteSpace(words))\n        {\n            throw new ArgumentException(\"Input words cannot be empty.\");\n        }\n\n        var normalized = TokenMapWordsToNumberNormalizer.Normalize(\n            words.Replace(\"'\", string.Empty).Replace(\"’\", string.Empty),\n            TokenMapNormalizationProfile.LowercaseReplacePeriodsWithSpaces);\n        var negative = false;\n\n        foreach (var negativePrefix in profile.NegativePrefixes)\n        {\n            if (!normalized.StartsWith(negativePrefix, StringComparison.Ordinal))\n            {\n                continue;\n            }\n\n            negative = true;\n            normalized = normalized[negativePrefix.Length..].Trim();\n            break;\n        }","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/WordsToNumber/LinkingAffixWordsToNumberConverter.cs#L13-L49","documentation":"LinkingAffixWordsToNumberConverter.TryConvert throws this ArgumentException at line 31 when the input is null, empty, or whitespace. Unlike the 'unrecognized word' throw, this one is inside the Try overload, so even TryToNumber will throw on empty input. The converter cannot normalize or tokenize an empty phrase, so it rejects it up front rather than returning a misleading false.","triggerScenarios":"Passing null, string.Empty, or a whitespace-only string (\"   \", tabs) to ToNumber or TryToNumber on a locale backed by the linking-affix converter. The IsNullOrWhiteSpace check at line 29 fires before any tokenization.","commonSituations":"Unvalidated UI input; reading a field that is blank in the data; trimming a value down to empty and then parsing it; a pipeline step that substitutes empty for missing data.","solutions":["Guard the input with !string.IsNullOrWhiteSpace(words) before calling any To/Try number method.","Treat blank input as a caller-side condition (return early, prompt again) rather than relying on the parser.","Add null-coalescing/normalization upstream so empty never reaches the converter."],"exampleFix":"// before\n\"   \".TryToNumber(out var n, culture);\n// after\nif (!string.IsNullOrWhiteSpace(input) && input.TryToNumber(out var n, culture))\n    Use(n);","handlingStrategy":"validation","validationCode":"// Guard empty/whitespace BEFORE calling (Try* also throws on empty).\nif (string.IsNullOrWhiteSpace(words))\n    return Result.Skip();\nreturn Result.Ok(words.TryToNumber(out var n, culture) ? n : 0);","typeGuard":null,"tryCatchPattern":"try { var n = words.ToNumber(culture); }\ncatch (ArgumentException ex) when (ex.Message == \"Input words cannot be empty.\")\n    { /* input was blank */ }","preventionTips":["Never assume Try* is non-throwing for empty input in Humanizer.","Centralize a !IsNullOrWhiteSpace guard for all number-word entry points.","Treat blank as a caller-side condition, not a parse failure."],"tags":["words-to-number","linking-affix","input-validation","argumentexception","parsing"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}