Humanizr/Humanizer · error · FormatException
Unit token '{unit.Symbol}' does not belong to the selected b
Error message
Unit token '{unit.Symbol}' does not belong to the selected byte-size unit system. What it means
Thrown by ByteSize.FindFormatUnit while interpreting a format string for a chosen unit system. After masking quoted/escaped literals, if the format contains a symbol belonging to the opposite system (e.g. a binary 'GiB' token while formatting with DecimalSi units, or a decimal 'GB' while using BinaryIec), the library refuses to silently mis-render it.
Source
Thrown at src/Humanizer/Bytes/ByteSize.cs:1028
return absoluteBytes >= 1
? new(1, ByteSymbol, DataUnit.Byte)
: new(1d / BitsInByte, BitSymbol, DataUnit.Bit);
}
static SystemUnit? FindFormatUnit(string? format, SystemUnit[] units)
{
if (string.IsNullOrWhiteSpace(format) || format == "G")
{
return null;
}
var maskedFormat = MaskFormatLiterals(format!);
var incompatibleUnits = ReferenceEquals(units, DecimalUnits) ? BinaryUnits : DecimalUnits;
foreach (var unit in incompatibleUnits)
{
if (maskedFormat.Contains(unit.Symbol, StringComparison.OrdinalIgnoreCase))
{
throw new FormatException($"Unit token '{unit.Symbol}' does not belong to the selected byte-size unit system.");
}
}
if (maskedFormat.Contains("EiB", StringComparison.OrdinalIgnoreCase))
{
throw new FormatException("EiB is outside the range supported by ByteSize.Bits.");
}
SystemUnit? selectedUnit = null;
var remainingFormat = maskedFormat;
foreach (var unit in units)
{
if (!remainingFormat.Contains(unit.Symbol, StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (selectedUnit is not null && selectedUnit.Value.DataUnit != unit.DataUnit)View on GitHub (pinned to ffc2b77c0f)
Solutions
- Match the format string's unit token to the active unit system (decimal SI uses kB/MB/GB/TB/PB/EB; binary IEC uses KiB/MiB/GiB/TiB/PiB).
- If you genuinely want both, render twice with separate unit systems and concatenate.
- Quote literal text containing unit-like letters with single quotes (e.g. '#.## "GiB"') so MaskFormatLiterals hides them from the scan.
Example fix
// before (DecimalSi context)
var text = size.ToString("#.## GiB");
// after
var text = size.ToString("#.## GB"); // token matches DecimalSi
// or, if GiB was intentional, switch the unit system first Defensive patterns
Strategy: validation
Validate before calling
static string NormalizeFormat(string format, ByteSizeUnitSystem system)
{
var binary = new HashSet<string> { "KiB", "MiB", "GiB", "TiB", "PiB" };
var decimalSi = new HashSet<string> { "kB", "MB", "GB", "TB", "PB", "EB" };
var disallowed = system == ByteSizeUnitSystem.BinaryIec ? decimalSi : binary;
foreach (var token in disallowed)
if (format.Contains(token, StringComparison.OrdinalIgnoreCase))
throw new ArgumentException($"Format contains incompatible token {token}.");
return format;
} Try / catch
try { return size.ToString(format); }
catch (FormatException) { throw new ArgumentException("Format token does not match the active unit system.", nameof(format)); } Prevention
- Match format tokens to the active unit system
- Keep format strings in resources keyed by system
- Quote literal unit-like text to hide it from the scanner
When it happens
Trigger: Calling ToString("#.## GiB", ...) on a ByteSize whose current unit system is DecimalSi, or calling Humanize with a format string that mixes 'MB' into a BinaryIec format. The masked format is scanned case-insensitively against the incompatible unit list.
Common situations: Copy-pasting a format string between code paths that use different unit systems, localizing UI where the format string comes from a resource file keyed to the wrong system, or upgrading to a version that enforces system-token separation that was previously lenient.
Related errors
- A byte-size format can contain only one distinct unit token.
- Value is not in the correct format
- EiB is outside the range supported by ByteSize.Bits.
- Unable to protect the byte-size unit token.
- Unknown byte-size unit system.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/ee00e1971ec0bcc1.
Report an issue: GitHub.