iOfficeAI/OfficeCLI · error · ArgumentException
Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:
Error message
Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:F7'. What it means
Thrown when the `anchor=` property (or the `ref=` alias mapped into `anchor`) is present but TryParseCellRangeAnchor cannot parse it as an A1-style cell or cell range. The parser only accepts the form `COLrow` or `COLrow:COLrow` (e.g. `B2`, `B2:F7`); anything else — a pixel value, a named range, an R1C1 string, an inverted or malformed token — fails the regex and throws. This is the cell-range grammar shared with OLE's anchor=, introduced for consistency across the drawing/cell/comment/table Add paths.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:613
// rectangle (B2:C3) so the shape has a visible extent.
// Using identical from/to markers produces a
// zero-width/height invisible shape in Excel.
if (TryParseCellRangeAnchor(refTrim, out var rc, out var rr, out _, out _))
refTrim = $"{refTrim}:{IndexToColumnName(rc + 2)}{rr + 2}";
else
refTrim = $"{refTrim}:{refTrim}";
}
properties["anchor"] = refTrim;
}
int sx, sy, sw, sh;
if (properties.TryGetValue("anchor", out var shpAnchorStr) && !string.IsNullOrWhiteSpace(shpAnchorStr))
{
if (properties.ContainsKey("width") | properties.ContainsKey("height")
| properties.ContainsKey("x") | properties.ContainsKey("y"))
Console.Error.WriteLine(
"Warning: 'x'/'y'/'width'/'height' are ignored when 'anchor' is provided (anchor defines the full rectangle).");
if (!TryParseCellRangeAnchor(shpAnchorStr, out var sxFrom, out var syFrom, out var sxTo, out var syTo))
throw new ArgumentException($"Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:F7'.");
sx = sxFrom;
sy = syFrom;
if (sxTo < 0) { sxTo = sx + 4; syTo = sy + 2; }
sw = sxTo - sx;
sh = syTo - sy;
}
else
{
(sx, sy, sw, sh) = ParseAnchorBounds(properties, "1", "1", "5", "3");
}
// Clamp the derived TwoCellAnchor span to Excel's grid so an
// x/y/width/height that walks the TO marker past the ceiling ends at the
// grid edge (what real Excel does) instead of being written out of range
// into a file Excel refuses to open. FROM out of grid still throws.
{
var (shpToCol, shpToRow) = ClampAnchorSpan(sx, sy, sx + sw, sy + sh,
shpAnchorStr ?? $"x={sx},y={sy},width={sw},height={sh}");
sw = shpToCol - sx;View on GitHub (pinned to 1ced45e900)
Solutions
- Use the A1 cell-range form `anchor=B2` or `anchor=B2:F7`.
- If you meant pixel/column-unit coordinates, drop `anchor=` and use `x=`, `y=`, `width=`, `height=` instead (the else-branch ParseAnchorBounds handles those).
- If you supplied `ref=`, ensure it is a real cell address; `ref=` is aliased to `anchor=` for single-cell placement.
Example fix
// before add ./book.xlsx /Sheet1 shape --type rectangle --prop anchor=100,100,200,80 // after add ./book.xlsx /Sheet1 shape --type rectangle --prop anchor=B2:F7
Defensive patterns
Strategy: validation
Validate before calling
// Use the same parser the handler uses to pre-validate the anchor.
if (!ExcelHandler.TryParseCellRangeAnchor(anchorStr,
out var fc, out var fr, out var tc, out var tr))
throw new InvalidOperationException(
$"anchor '{anchorStr}' must be like 'B2' or 'B2:F7'"); Type guard
static bool IsValidCellAnchor(string? s)
=> System.Text.RegularExpressions.Regex.IsMatch(
s ?? "", @"^[A-Za-z]{1,3}\d+(:[A-Za-z]{1,3}\d+)?$"); Try / catch
try { handler.Add(...); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid anchor"))
{
// prompt the user for a corrected A1 range
} Prevention
- Decide once whether you use cell-range anchors (anchor=) or numeric coords (x/y/width/height) and stay consistent.
- Pre-validate any user-supplied cell string with a single cell-reference regex before passing it as anchor=.
- Do not mix anchor= with x/y/width/height; the handler warns and lets anchor win.
When it happens
Trigger: Passing `--prop anchor=100,200` (pixel coordinates) or `--prop anchor=R1C1` or `--prop anchor=B2-F7` (hyphen instead of colon) or an empty/garbage anchor string. Also fires when `ref=` resolves to a non-cell value and is mapped into anchor=.
Common situations: Mixing up the legacy x/y/width/height numeric form with the cell-range anchor form; copying anchor syntax from a different tool (SpreadsheetML, Google Sheets, R1C1); leftover whitespace or a stray quote around the cell reference.
Related errors
- Anchor cell '{original}' is outside Excel's grid (A1..XFD104
- Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D
- Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:
- Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6
- Sheet not found: {shpSheetName}
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/bc6336189de8c244.
Report an issue: GitHub.