Humanizr/Humanizer · error · FormatException

Unable to protect the byte-size unit token.

Error message

Unable to protect the byte-size unit token.

What it means

Thrown by ByteSize.FindFormatSentinel when no character in the Unicode Private Use Area (U+E000..U+F8FF) is absent from all the supplied values. The library uses a PUA character as a temporary sentinel to protect unit tokens during format substitution; if every PUA code point already appears in the inputs, no sentinel can be chosen.

Source

Thrown at src/Humanizer/Bytes/ByteSize.cs:1133

                    result[index] = '\0';
                }
            }
        }

        return new(result);
    }

    static string FindFormatSentinel(params string[] values)
    {
        for (var candidate = '\uE000'; candidate <= '\uF8FF'; candidate++)
        {
            if (values.All(value => !value.Contains(candidate)))
            {
                return candidate.ToString();
            }
        }

        throw new FormatException("Unable to protect the byte-size unit token.");
    }

    static string ReplaceFormatToken(string format, string token, string replacement)
    {
        var maskedFormat = MaskFormatLiterals(format);
        return ReplaceOrdinalIgnoreCase(format, maskedFormat, token, replacement);
    }

    static string ReplaceOrdinalIgnoreCase(string value, string oldValue, string newValue) =>
        ReplaceOrdinalIgnoreCase(value, value, oldValue, newValue);

    static string ReplaceOrdinalIgnoreCase(string value, string searchValue, string oldValue, string newValue)
    {
        var searchStart = 0;
        var index = CultureInfo.InvariantCulture.CompareInfo.IndexOf(
            searchValue,
            oldValue,
            searchStart,

View on GitHub (pinned to ffc2b77c0f)

Solutions

  1. Strip Private Use Area characters from the format string before formatting the ByteSize.
  2. Avoid routing arbitrary UI/icon-font text through ByteSize.ToString; format the number first, then concatenate icons.
  3. If unavoidable, pre-process the input to remap PUA characters to a safe range.

Example fix

// before
var text = size.ToString(formatWithIconGlyphs);

// after
var safeFormat = new string(formatWithIconGlyphs.Where(c => c < '\uE000' || c > '\uF8FF').ToArray());
var text = size.ToString(safeFormat);
Defensive patterns

Strategy: validation

Validate before calling

static string StripPrivateUseArea(string format) =>
    new string(format.Where(c => c < '\uE000' || c > '\uF8FF').ToArray());

Try / catch

try { return size.ToString(format); }
catch (FormatException) { throw new ArgumentException("Format contains too many Private Use Area characters.", nameof(format)); }

Prevention

When it happens

Trigger: Calling a format/rendering path that invokes FindFormatSentinel with strings that collectively contain all 6400 Private Use Area characters. In practice this only happens when the format string or unit payload is itself constructed from PUA-heavy data (custom icon fonts, emoji-style ligatures stored in the PUA).

Common situations: Embedding icon-font glyphs (U+E000-U+F8FF range) into byte-size format strings, or piping PUA-tagged telemetry through a formatter that builds its format dynamically from such data. Extremely rare in normal usage.

Related errors


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