iOfficeAI/OfficeCLI · error · ArgumentException
Invalid crop '{cropAll}'. Expected four comma-separated perc
Error message
Invalid crop '{cropAll}'. Expected four comma-separated percentages in l,t,r,b order (e.g. '10,15,5,20'). What it means
ParseSrcRect's 'crop' composite branch accepts 'l,t,r,b' as exactly four comma-separated percentages (the exact form Get emits, supported so dump->batch replay works). If there are not exactly four parts or any part fails ParseCropPercent, it throws. Order is left, top, right, bottom. This branch only runs when crop has no '=' (the key form routes to srcRect).
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Helpers.Drawing.cs:128
anyParsed = true;
}
if (!anyParsed)
throw new ArgumentException(
$"Invalid srcRect '{compound}'. Expected 'l=10,r=10,t=5,b=5' (any subset; values are percent 0-100). "
+ "For raw l/t/r/b numbers use cropLeft/cropTop/cropRight/cropBottom keys.");
}
// CONSISTENCY(picture-crop): bare composite `crop=l,t,r,b` — the exact
// form Get emits (and pptx Add already accepts). Without it, dump→batch
// replay warned UNSUPPORTED and silently dropped the srcRect.
if (properties.TryGetValue("crop", out var cropAll) && !string.IsNullOrWhiteSpace(cropAll)
&& !cropAll.Contains('='))
{
var cropParts = cropAll.Split(',');
var cropVals = cropParts.Length == 4
? cropParts.Select(ParseCropPercent).ToArray()
: null;
if (cropVals == null || !cropVals.All(v => v.HasValue))
throw new ArgumentException(
$"Invalid crop '{cropAll}'. Expected four comma-separated percentages in l,t,r,b order (e.g. '10,15,5,20').");
l = cropVals[0]; t = cropVals[1]; r = cropVals[2]; b = cropVals[3];
}
foreach (var (key, fld) in new[] { ("crop.l", "l"), ("crop.r", "r"), ("crop.t", "t"), ("crop.b", "b") })
{
if (properties.TryGetValue(key, out var vs) && !string.IsNullOrWhiteSpace(vs))
{
var v = ParseCropPercent(vs);
if (!v.HasValue) continue;
switch (fld) { case "l": l = v; break; case "r": r = v; break; case "t": t = v; break; case "b": b = v; break; }
}
}
// CONSISTENCY(picture-crop): Office-API-style `cropLeft`/`cropRight`
// /`cropTop`/`cropBottom` aliases. Accept fraction (<=1 → *100%) or
// percent (>1 → as-is); e.g. `cropLeft=0.1` and `cropLeft=10` both
// mean 10% crop from left.
foreach (var (key, fld) in new[] { ("cropLeft", "l"), ("cropRight", "r"), ("cropTop", "t"), ("cropBottom", "b") })
{View on GitHub (pinned to 1ced45e900)
Solutions
- Provide exactly four percentages in l,t,r,b order: crop=10,15,5,20.
- For partial crops use the per-side keys crop.l/crop.t/crop.r/crop.b.
- Round-trip via Get to obtain the canonical crop string and replay it verbatim.
- Validate the part count and numeric parse before calling Add.
Example fix
// before props["crop"] = "10,15,5"; // only three -> throw props["crop"] = "10;15;5;20"; // wrong separator -> throw // after props["crop"] = "10,15,5,20"; // exactly four, l,t,r,b // or partial: props["crop.l"] = "10"; props["crop.r"] = "5";
Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidCropComposite(string s)
{
var parts = s.Split(',');
return parts.Length == 4
&& parts.All(p => int.TryParse(p.Trim(), out var v) && v >= 0 && v <= 100);
}
if (!string.IsNullOrWhiteSpace(crop) && !crop.Contains('=') && !IsValidCropComposite(crop))
throw new ArgumentException($"Bad crop '{crop}'; expected four l,t,r,b percentages"); Type guard
static bool IsValidCropComposite(string s) =>
s.Split(',') is { Length: 4 } parts
&& parts.All(p => int.TryParse(p.Trim(), out var v) && v is >= 0 and <= 100); Prevention
- Provide exactly four comma-separated percentages in l,t,r,b order.
- Use crop.l/crop.t/crop.r/crop.b keys for partial crops.
- Use the srcRect key form for explicit l/r/t/b assignment.
- Replay the exact crop string Get emits to avoid reformatting mistakes.
When it happens
Trigger: crop=10,15,5 (only three); crop=10,abc,5,20 (non-numeric); crop=10;15;5;20 (semicolon separator); crop=10,15,5,20,1 (five values).
Common situations: Truncated crop string from a manual edit; locale using ';' as list separator; wrong element count or wrong order.
Related errors
- Invalid srcRect '{compound}'. Expected 'l=10,r=10,t=5,b=5' (
- Picture/shape {key} is out of range for a oneCell/absolute d
- Sheet not found: {shpSheetName}
- Defined name '{nrName}' collides with the table name '{exist
- Property 'sqref' (or 'range'/'ref') is required for validati
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/a28663fa48ded3d4.
Report an issue: GitHub.