Humanizr/Humanizer · error · ArgumentException

Empty or invalid Metric string.

Error message

Empty or invalid Metric string.

What it means

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.

Source

Thrown at src/Humanizer/MetricNumeralExtensions.cs:294

        }

        return BuildRepresentation(input, formats, decimals);
    }

    /// <summary>
    /// Clean or handle any wrong input
    /// </summary>
    /// <param name="input">Metric representation to clean</param>
    /// <returns>A cleaned representation</returns>
    static string CleanRepresentation(string input)
    {
        ArgumentNullException.ThrowIfNull(input);

        input = input.Trim();
        input = ReplaceNameBySymbol(input);
        if (input.Length == 0 || input.IsInvalidMetricNumeral())
        {
            throw new ArgumentException("Empty or invalid Metric string.", nameof(input));
        }

        return input.Replace(" ", string.Empty);
    }

    /// <summary>
    /// Build a number from a metric representation or from a number
    /// </summary>
    /// <param name="input">A Metric representation to parse to a number</param>
    /// <param name="last">The last character of input</param>
    /// <returns>A number build from a Metric representation</returns>
    static double BuildNumber(string input, char last) =>
        char.IsLetter(last)
            ? BuildMetricNumber(input, last)
            : double.Parse(input);

    /// <summary>
    /// Build a number from a metric representation

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Validate the input is non-empty and matches the expected metric pattern before calling FromMetric.
  2. Use a try/catch around ArgumentException and provide a fallback or error message to the user.
  3. Ensure the upstream data source produces {number}{symbol} format (e.g. "1k" not "1 kilo").

Example fix

// before
var num = userInput.FromMetric();

// after
if (string.IsNullOrWhiteSpace(userInput))
    return 0d;
var num = userInput.FromMetric();
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidMetricInput(string? input)
{
    if (string.IsNullOrWhiteSpace(input)) return false;
    var trimmed = input.Trim();
    var last = trimmed[^1];
    var numberPart = char.IsLetter(last) ? trimmed[..^1] : trimmed;
    return double.TryParse(numberPart, out _);
}

Try / catch

try
{
    return input.FromMetric();
}
catch (ArgumentException ex) when (ex.Message.Contains("Empty or invalid Metric"))
{
    return 0d;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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