iOfficeAI/OfficeCLI · error · ArgumentException

Invalid 'margin' value '{value}'. Expected single length (e.

Error message

Invalid 'margin' value '{value}'. Expected single length (e.g. '4pt', '0.5cm') or 4-CSV 'L,T,R,B'.

What it means

Thrown by the margin parser when the value does not split into exactly 1 or exactly 4 non-empty comma-separated parts. A single part applies the same margin to all four sides; a 4-CSV 'L,T,R,B' sets each side independently. Parts are parsed as lengths via SpacingConverter.ParsePoints (so '4pt', '0.5cm', '0.1in' all work), then converted to EMU.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs:1347

    /// Accepts unit-qualified "14pt"/"0.5cm"/"0.2in"/bare-points for uniform
    /// inset, OR a 4-CSV "Lpt,Tpt,Rpt,Bpt" matching Get's readback format.
    /// CONSISTENCY(spacing-units): mirrors SpacingConverter usage so that
    /// margin's input vocabulary matches Get's "Npt"/"L,T,R,B" output.
    /// </summary>
    private static (int L, int T, int R, int B) ParseShapeMarginToEmu(string value)
    {
        var parts = (value ?? string.Empty).Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length == 4)
        {
            int Emu(string s) => (int)Math.Round(SpacingConverter.ParsePoints(s) * EmuConverter.EmuPerPoint);
            return (Emu(parts[0]), Emu(parts[1]), Emu(parts[2]), Emu(parts[3]));
        }
        if (parts.Length == 1)
        {
            var emu = (int)Math.Round(SpacingConverter.ParsePoints(parts[0]) * EmuConverter.EmuPerPoint);
            return (emu, emu, emu, emu);
        }
        throw new ArgumentException(
            $"Invalid 'margin' value '{value}'. Expected single length (e.g. '4pt', '0.5cm') or 4-CSV 'L,T,R,B'.");
    }

    private static Drawing.ShapeTypeValues ParseExcelShapePreset(string name)
    {
        var key = (name ?? string.Empty).Trim().ToLowerInvariant();
        if (string.IsNullOrEmpty(key))
            return Drawing.ShapeTypeValues.Rectangle;
        if (_shapePresetMap.TryGetValue(key, out var val))
            return val;
        // R20-01: Unknown preset falls back to rectangle, but emit a stderr
        // warning so users notice (silent rect was found by audit). 'custom'
        // is the common case — it would require a custGeom path which
        // officecli doesn't expose, so suggest raw-set explicitly.
        if (key == "custom")
        {
            Console.Error.WriteLine(
                "Warning: preset='custom' requires a custGeom path which officecli does not expose; " +

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a single length for uniform margins: margin='4pt'.
  2. Use exactly four comma-separated lengths in L,T,R,B order: margin='4pt,2pt,4pt,2pt'.
  3. Do not use CSS space shorthand or TRBL order; OfficeCLI uses explicit comma-CSV in L,T,R,B.
  4. Remove trailing/leading commas and ensure no empty fields.

Example fix

// before
shape margin=4pt 2pt 4pt 2pt
// after
shape margin=4pt,2pt,4pt,2pt
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidMargin(string value)
{
    var parts = (value ?? string.Empty)
        .Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
    return parts.Length == 1 || parts.Length == 4;
}

Type guard

static bool IsMarginSpec(string s)
{
    var n = (s ?? string.Empty)
        .Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Length;
    return n == 1 || n == 4;
}

Try / catch

try { var (l,t,r,b) = ParseMargin(value); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid 'margin'"))
{
    // fall back to a single uniform margin, or surface a user error
}

Prevention

When it happens

Trigger: Passing 2 or 3 values like margin='4pt,2pt' or margin='4pt,2pt,1pt'; using space separation like margin='4pt 2pt 1pt 0' (the whole thing becomes one part that fails point parsing only if it had commas); mixing the single-value and per-side forms; trailing commas producing empty entries that get removed and drop the count below 4.

Common situations: Copying CSS 'margin: 4pt 2pt 1pt 0' shorthand (space-separated, not comma); expecting TRBL order like CSS (the parser is L,T,R,B); passing partial per-side values; AI assistants emitting fewer than 4 sides when per-side was intended.

Related errors


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