{"record":{"id":"b914c77cc2429a22","repo":"Humanizr/Humanizer","slug":"decimal-marker-must-not-be-empty","errorCode":null,"errorMessage":"Decimal marker must not be empty.","messagePattern":"Decimal marker must not be empty\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/WordsToNumber/LocalizedWordsToDecimalNumberConverter.cs","lineNumber":28,"sourceCode":"    readonly CompareInfo compareInfo;\n    readonly string decimalMarker;\n    readonly FractionalDigit[] fractionalDigits;\n    readonly IWordsToNumberConverter integerConverter;\n    readonly bool allowsJoinedTokens;\n    readonly bool allowsEnglishOverflowComposition;\n    readonly NegativeAffix[] negativePrefixes;\n    readonly NegativeAffix[] negativeSuffixes;\n\n    public LocalizedWordsToDecimalNumberConverter(\n        CultureInfo culture,\n        string decimalMarker,\n        string[] negativePrefixes,\n        string[] negativeSuffixes)\n    {\n        compareInfo = culture.CompareInfo;\n        this.decimalMarker = NormalizeWhitespace(decimalMarker);\n        if (this.decimalMarker.Length == 0)\n            throw new ArgumentException(\"Decimal marker must not be empty.\", nameof(decimalMarker));\n\n        integerConverter = Configurator.GetWordsToNumberConverter(culture);\n        allowsJoinedTokens = integerConverter is EastAsianPositionalWordsToNumberConverter;\n        allowsEnglishOverflowComposition =\n            string.Equals(culture.TwoLetterISOLanguageName, \"en\", StringComparison.OrdinalIgnoreCase);\n        this.negativePrefixes = NormalizePrefixes(negativePrefixes);\n        this.negativeSuffixes = NormalizeSuffixes(negativeSuffixes);\n        fractionalDigits = CreateFractionalDigits(culture);\n    }\n\n    internal string DecimalMarker => decimalMarker;\n\n    /// <inheritdoc />\n    public decimal Convert(string words)\n    {\n        ArgumentNullException.ThrowIfNull(words);\n\n        if (!TryConvert(words, out var parsedValue, out var unrecognizedNumber))","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/WordsToNumber/LocalizedWordsToDecimalNumberConverter.cs#L10-L46","documentation":"LocalizedWordsToDecimalNumberConverter's constructor throws this ArgumentException at line 28 when decimalMarker normalizes to an empty string. The decimal grammar needs exactly one locale-specific marker to split integer and fractional parts, so an empty marker is unrecoverable. The converter is internal and built from locale data, so an empty marker is a locale-authoring defect.","triggerScenarios":"A locale's decimal-word configuration supplies an empty or whitespace-only decimal marker; the marker value is stripped to empty by NormalizeWhitespace; or the generator wires an empty marker. Construction happens lazily when ToDecimalNumber/TryToDecimalNumber first resolves the culture.","commonSituations":"A new locale with decimal words added but its decimal marker key left blank; a YAML typo that yields an empty string; regenerating after a marker rename.","solutions":["Provide a non-empty locale-specific decimal marker (e.g. 'point', 'virgule', the localized 'and'-style token) in the locale decimal configuration.","Regenerate locale source and run the locale's decimal word tests.","Add a construction assertion in locale tests verifying the converter builds for that culture."],"exampleFix":"// before (locale decimal config)\ndecimalMarker: \"\"\n// after\ndecimalMarker: \"point\",  // localized marker for splitting integer/fractional words","handlingStrategy":"validation","validationCode":"// Authoring-time guard: confirm the decimal converter builds for the culture.\nvar decimalConverter = Configurator.GetWordsToDecimalNumberConverter(targetCulture);\nAssert.False(decimalConverter is UnsupportedWordsToDecimalNumberConverter);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provide a non-empty locale-specific decimal marker in the decimal config.","Add a locale test that constructs the decimal converter and asserts it is not the unsupported stub.","Regenerate locale source after changing decimal data."],"tags":["words-to-decimal","decimal","locale-authoring","config","argumentexception"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}