iOfficeAI/OfficeCLI · error · ArgumentException
Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:
Error message
Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:E6'. What it means
Thrown when the OLE 'anchor' property fails to match the expected cell or cell-range pattern. The OLE anchor parser uses its own inline regex ^([A-Z]+)(\d+)(?::([A-Z]+)(\d+))?$ (case-insensitive) rather than the shared TryParseCellRangeAnchor. A width/height warning is emitted first (those are ignored with anchor=), then the anchor format error fires if parsing fails.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:146
int oleFromCol, oleFromRow, oleToCol, oleToRow;
// FromMarker offsets are always zero (anchor starts at cell boundary);
// ToMarker offsets carry the sub-cell EMU remainder for unit-qualified
// width/height inputs, preserving round-trip precision.
const long oleFromColOff = 0, oleFromRowOff = 0;
long oleToColOff = 0, oleToRowOff = 0;
if (properties.TryGetValue("anchor", out var oleAnchorStr) && !string.IsNullOrWhiteSpace(oleAnchorStr))
{
// CONSISTENCY(ole-width-units): anchor= defines the full
// rectangle (start+end cells), so width/height on the same
// Add call would be ambiguous and are silently dropped.
// Warn loudly rather than fail, so existing scripts keep
// working but users notice the dropped value.
if (properties.ContainsKey("width") | properties.ContainsKey("height"))
Console.Error.WriteLine(
"Warning: 'width'/'height' are ignored when 'anchor' is provided (anchor defines the full rectangle).");
var m = Regex.Match(oleAnchorStr, @"^([A-Z]+)(\d+)(?::([A-Z]+)(\d+))?$", RegexOptions.IgnoreCase);
if (!m.Success)
throw new ArgumentException($"Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:E6'.");
// CONSISTENCY(xdr-coords): XDR ColumnId/RowId are 0-based;
// ColumnNameToIndex returns 1-based, so subtract 1 here.
oleFromCol = ColumnNameToIndex(m.Groups[1].Value) - 1;
oleFromRow = int.Parse(m.Groups[2].Value) - 1;
ValidateAnchorCell(oleFromCol, oleFromRow, oleAnchorStr.Split(':')[0]);
if (m.Groups[3].Success)
{
oleToCol = ColumnNameToIndex(m.Groups[3].Value) - 1;
oleToRow = int.Parse(m.Groups[4].Value) - 1;
ValidateAnchorCell(oleToCol, oleToRow, oleAnchorStr.Split(':')[1]);
NormalizeAnchorRect(ref oleFromCol, ref oleFromRow, ref oleToCol, ref oleToRow);
}
else
{
oleToCol = oleFromCol + 2;
oleToRow = oleFromRow + 3;
}
}View on GitHub (pinned to 1ced45e900)
Solutions
- Use 'B2' for a single-cell anchor or 'B2:E6' for a range.
- Use colon (:) not comma (,) for the range separator.
- If you need numeric positioning, drop anchor= and use x=/y=/width=/height= instead.
- Ensure column letters are valid (A-XFD) and rows are 1-1048576.
Example fix
// before add /Sheet1 --type ole --src obj.xlsx --anchor "B2,E6" // after add /Sheet1 --type ole --src obj.xlsx --anchor "B2:E6"
Defensive patterns
Strategy: validation
Validate before calling
// Validate OLE anchor format before the add call
if (properties.TryGetValue("anchor", out var oleAnchor) && !string.IsNullOrWhiteSpace(oleAnchor))
{
if (!System.Text.RegularExpressions.Regex.IsMatch(
oleAnchor, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase))
throw new InvalidOperationException(
$"Invalid OLE anchor '{oleAnchor}'. Expected 'B2' or 'B2:E6'.");
} Type guard
static bool IsValidOleAnchor(string? s) =>
!string.IsNullOrWhiteSpace(s) &&
System.Text.RegularExpressions.Regex.IsMatch(
s, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase); Try / catch
try { handler.AddOle(parentPath, properties); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid anchor:"))
{
Console.Error.WriteLine($"{ex.Message} Use 'B2' or 'B2:E6' format.");
} Prevention
- Use only A1-style cell references for OLE anchor=.
- Separate range endpoints with a colon (:), never a comma.
- Pre-validate anchor strings with a regex.
- Use x=/y=/width=/height= for numeric positioning instead of anchor=.
When it happens
Trigger: Setting properties["anchor"] to anything not matching ColRow or ColRow:ColRow, e.g. 'B-2', 'row5col2', 'B2,E6', 'B2:'. Also fires if ValidateAnchorCell rejects a cell outside the grid (A0, XFE1).
Common situations: User copies pixel-based or R1C1 coordinates. User uses a comma instead of a colon for ranges. Copy-paste introduces invisible characters.
Related errors
- Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D
- Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6
- Anchor cell '{original}' is outside Excel's grid (A1..XFD104
- Anchor must be a column path like /{colSheetName}/col[L], go
- Sheet not found: {oleSheetName}
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/a6c4acaa3ae0a971.
Report an issue: GitHub.