{"record":{"id":"3e647271ed21a849","repo":"Humanizr/Humanizer","slug":"empty-or-invalid-metric-string","errorCode":null,"errorMessage":"Empty or invalid Metric string.","messagePattern":"Empty or invalid Metric string\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/MetricNumeralExtensions.cs","lineNumber":294,"sourceCode":"        }\n\n        return BuildRepresentation(input, formats, decimals);\n    }\n\n    /// <summary>\n    /// Clean or handle any wrong input\n    /// </summary>\n    /// <param name=\"input\">Metric representation to clean</param>\n    /// <returns>A cleaned representation</returns>\n    static string CleanRepresentation(string input)\n    {\n        ArgumentNullException.ThrowIfNull(input);\n\n        input = input.Trim();\n        input = ReplaceNameBySymbol(input);\n        if (input.Length == 0 || input.IsInvalidMetricNumeral())\n        {\n            throw new ArgumentException(\"Empty or invalid Metric string.\", nameof(input));\n        }\n\n        return input.Replace(\" \", string.Empty);\n    }\n\n    /// <summary>\n    /// Build a number from a metric representation or from a number\n    /// </summary>\n    /// <param name=\"input\">A Metric representation to parse to a number</param>\n    /// <param name=\"last\">The last character of input</param>\n    /// <returns>A number build from a Metric representation</returns>\n    static double BuildNumber(string input, char last) =>\n        char.IsLetter(last)\n            ? BuildMetricNumber(input, last)\n            : double.Parse(input);\n\n    /// <summary>\n    /// Build a number from a metric representation","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/MetricNumeralExtensions.cs#L276-L312","documentation":"Thrown by FromMetric(string) when the input, after trimming and name-to-symbol replacement, is either empty or fails double.TryParse validation. FromMetric only accepts the pattern {number}{symbol} (e.g. \"1k\", \"100m\") or a bare number. Anything else is treated as invalid metric input.","triggerScenarios":"Calling \"\".FromMetric(), \"   \".FromMetric(), \"abc\".FromMetric(), or \"1x\".FromMetric() where 'x' is not a recognized unit prefix. Also fires for strings that aren't parseable as doubles even without a symbol suffix.","commonSituations":"Parsing user-entered or config-file metric strings without sanitizing them. Reading values from a format that uses full unit names (e.g. \"1 kilo\") instead of symbols. Passing null-adjacent empty strings from deserialization.","solutions":["Validate the input is non-empty and matches the expected metric pattern before calling FromMetric.","Use a try/catch around ArgumentException and provide a fallback or error message to the user.","Ensure the upstream data source produces {number}{symbol} format (e.g. \"1k\" not \"1 kilo\")."],"exampleFix":"// before\nvar num = userInput.FromMetric();\n\n// after\nif (string.IsNullOrWhiteSpace(userInput))\n    return 0d;\nvar num = userInput.FromMetric();","handlingStrategy":"validation","validationCode":"static bool IsValidMetricInput(string? input)\n{\n    if (string.IsNullOrWhiteSpace(input)) return false;\n    var trimmed = input.Trim();\n    var last = trimmed[^1];\n    var numberPart = char.IsLetter(last) ? trimmed[..^1] : trimmed;\n    return double.TryParse(numberPart, out _);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    return input.FromMetric();\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Empty or invalid Metric\"))\n{\n    return 0d;\n}","preventionTips":["Sanitize external data before calling FromMetric.","Use the IsValidMetricInput guard for user-entered strings.","Test with empty, whitespace, and non-metric inputs."],"tags":["metric","argument-validation","input-parsing"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}