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
- Use a single length for uniform margins: margin='4pt'.
- Use exactly four comma-separated lengths in L,T,R,B order: margin='4pt,2pt,4pt,2pt'.
- Do not use CSS space shorthand or TRBL order; OfficeCLI uses explicit comma-CSV in L,T,R,B.
- 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
- Use a single length for uniform margins or exactly four comma-separated L,T,R,B values.
- Do not use CSS space shorthand or TRBL order.
- Remove trailing/leading commas and empty fields.
- Pre-validate the part count is 1 or 4 before calling.
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
- gradientFill requires at least two '-' separated colors; got
- Invalid 'rotation' value: '{value}'. Expected a number in de
- Invalid length value '{value}'. Must be non-negative.
- Property 'sqref' (or 'range'/'ref') is required for validati
- Invalid srcRect '{compound}'. Expected 'l=10,r=10,t=5,b=5' (
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/658f68e7c01cb273.
Report an issue: GitHub.