iOfficeAI/OfficeCLI · error · ArgumentException

Invalid length value '{value}'. Must be non-negative.

Error message

Invalid length value '{value}'. Must be non-negative.

What it means

Thrown by ParsePoints when the parsed length value is negative. ParsePoints is used for non-negative length slots such as XLSX shape margins, treating bare numbers as points (CONSISTENCY spacing-units). Different message text ('length ... Must be non-negative') distinguishes it from the spacing guard. ArgumentException.

Source

Thrown at src/officecli/Core/SpacingConverter.cs:123

    /// unit-qualified "12pt", "0.5cm", "0.5in", "-1cm", "-12pt", or a bare
    /// signed number (treated as points). Used for PPTX paragraph indent
    /// which permits hanging-indent style negatives. CONSISTENCY(pptx-bare-as-points).
    /// </summary>
    public static double ParsePointsSigned(string value)
    {
        return ParseSpacingToPointsSigned(value, bareIsPoints: true);
    }

    /// <summary>
    /// Parse a length value to points. Accepts unit-qualified "12pt", "0.5cm",
    /// "0.5in" or bare number (treated as points). Used for XLSX shape margin
    /// to mirror Get's "Npt" output. CONSISTENCY(spacing-units).
    /// </summary>
    public static double ParsePoints(string value)
    {
        var points = ParseSpacingToPoints(value, bareIsPoints: true);
        if (points < 0)
            throw new ArgumentException($"Invalid length value '{value}'. Must be non-negative.");
        return points;
    }

    // ────────────────────────────────────────────────────────────────
    //  lineSpacing  →  Word (twips + LineRule)
    // ────────────────────────────────────────────────────────────────

    /// <summary>
    /// Parse line spacing for Word. Returns (twips, isMultiplier).
    /// "1.5x" or "150%" → (360, true)  — Auto rule, 240 × multiplier
    /// "18pt"           → (360, true=false) — Exact rule, pt × 20
    /// "0.5cm"          → converted to pt, then Exact
    /// bare number      → (number, true) — Auto rule, backward compat (raw twips)
    /// </summary>
    public static (int Twips, bool IsMultiplier) ParseWordLineSpacing(string value)
    {
        var trimmed = value.Trim();

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a non-negative length (e.g. '5pt', '0').
  2. If a negative offset is genuinely needed, confirm the target property accepts it and use the signed parser path.
  3. Check you are setting a margin, not an indent.

Example fix

// before
set shape margin left=-5pt
// after
set shape margin left=5pt
Defensive patterns

Strategy: validation

Validate before calling

var pts = SpacingConverter.ParsePoints(value);
if (pts < 0) throw new ArgumentException($"Non-negative length required: {value}");
// For offsets that allow negatives, use ParsePointsSigned.

Try / catch

try { var pts = SpacingConverter.ParsePoints(value); }
catch (ArgumentException ex) when (ex.Message.Contains("Must be non-negative"))
{ /* use a non-negative length */ }

Prevention

When it happens

Trigger: Passing a negative length to a slot routed through ParsePoints — e.g. an Excel shape margin ('-5pt') or any handler using EmuConverter via ParsePoints.

Common situations: A negative value intended for an offset/indent is applied to a margin that must be non-negative, or a signed measurement leaks into a length field.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/a4102d296203157e. Report an issue: GitHub.