iOfficeAI/OfficeCLI · error · ArgumentException
Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6
Error message
Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6', or one of 'oneCell'/'twoCell'/'absolute'. What it means
Thrown by AddPicture when the 'anchor' property is present, is not a recognized anchorMode token (oneCell/twoCell/absolute), and fails to parse as a cell-range reference via TryParseCellRangeAnchor. The picture branch first checks IsAnchorModeToken; only if that returns false does it attempt cell-range parsing. This is the broadest anchor error message because pictures accept three input shapes: cell ('B2'), range ('B2:E6'), or mode token ('oneCell').
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs:307
// DrawingsPart (and possibly the media blob) was already attached,
// leaving an empty <xdr:wsDr/> container plus orphaned xl/media
// bytes in the saved file even though the add reported an error.
var (xlImgStream, imgPartType) = OfficeCli.Core.ImageSource.Resolve(imgPath);
using var xlImgDispose = xlImgStream;
var picAnchorRaw = properties.GetValueOrDefault("anchor");
var picAnchorModeExplicit = properties.GetValueOrDefault("anchorMode");
bool picHasRange = false;
int picRangeFromCol = 0, picRangeFromRow = 0, picRangeToCol = -1, picRangeToRow = -1;
// `anchor=` is either a cell-range ("B2" / "B2:E6") or an
// anchorMode token ("oneCell"/"twoCell"/"absolute"). Prefer the
// cell-range interpretation; fall back to mode-token only when
// the value is a recognized token. Explicit `anchorMode=` wins
// the mode selection regardless.
if (!string.IsNullOrWhiteSpace(picAnchorRaw) && !IsAnchorModeToken(picAnchorRaw))
{
if (!TryParseCellRangeAnchor(picAnchorRaw, out picRangeFromCol, out picRangeFromRow, out picRangeToCol, out picRangeToRow))
throw new ArgumentException($"Invalid anchor: '{picAnchorRaw}'. Expected e.g. 'B2', 'B2:E6', or one of 'oneCell'/'twoCell'/'absolute'.");
picHasRange = true;
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 a cell range (anchor defines the full rectangle).");
}
var picAnchorMode = (picAnchorModeExplicit
?? (picHasRange ? "twoCell" : picAnchorRaw)
?? "twoCell").Trim().ToLowerInvariant();
var picDrawingsPart = picWorksheet.DrawingsPart
?? picWorksheet.AddNewPart<DrawingsPart>();
if (picDrawingsPart.WorksheetDrawing == null)
{
picDrawingsPart.WorksheetDrawing = new XDR.WorksheetDrawing();
picDrawingsPart.WorksheetDrawing.Save();
View on GitHub (pinned to 1ced45e900)
Solutions
- Use a single cell like 'B2', a colon-separated range like 'B2:E6', or one of the mode tokens 'oneCell'/'twoCell'/'absolute'.
- Drop anchor= and use x=/y=/width=/height= for numeric positioning.
- Check for typos in mode-token names (case-insensitive, but must match exactly: oneCell, twoCell, absolute).
- Ensure range separators are colons (:), not commas or semicolons.
Example fix
// before add /Sheet1 --type picture --src logo.png --anchor "top-left" // after add /Sheet1 --type picture --src logo.png --anchor "B2:E6"
Defensive patterns
Strategy: validation
Validate before calling
// Validate picture anchor before the add call
if (properties.TryGetValue("anchor", out var picAnchor) && !string.IsNullOrWhiteSpace(picAnchor))
{
var isModeToken = picAnchor.Trim().ToLowerInvariant() is "onecell" or "twocell" or "absolute";
var isCellRange = System.Text.RegularExpressions.Regex.IsMatch(
picAnchor, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase);
if (!isModeToken && !isCellRange)
throw new InvalidOperationException(
$"Invalid picture anchor '{picAnchor}'. Expected a cell ('B2'), range ('B2:E6'), " +
"or mode token ('oneCell'/'twoCell'/'absolute').");
} Type guard
static bool IsValidPictureAnchor(string? s)
{
if (string.IsNullOrWhiteSpace(s)) return false;
var v = s.Trim().ToLowerInvariant();
if (v is "onecell" or "twocell" or "absolute") return true;
return System.Text.RegularExpressions.Regex.IsMatch(
s, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase);
} Try / catch
try { handler.AddPicture(parentPath, type, position, properties); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid anchor:"))
{
Console.Error.WriteLine($"{ex.Message} Use a cell, range, or mode token.");
} Prevention
- Use A1-style cells ('B2'), colon-separated ranges ('B2:E6'), or the exact mode tokens (oneCell, twoCell, absolute).
- Never use commas or semicolons as range separators.
- Pre-validate anchor strings with a combined regex + mode-token check.
- Fall back to x=/y=/width=/height= for numeric positioning when anchor format is uncertain.
When it happens
Trigger: Setting properties["anchor"] to a value that is neither a recognized mode token nor a valid cell/range. Examples: 'B-2', 'top-left', 'absolute_anchor', 'B2;E6'. If the value IS a mode token, IsAnchorModeToken returns true and no error fires. If it is a cell/range that fails parsing, this error fires.
Common situations: User passes a descriptive word that is not one of the three recognized tokens. User uses wrong separators (semicolon, comma). User copies an anchor from a non-Excel context.
Related errors
- Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D
- Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:
- Anchor cell '{original}' is outside Excel's grid (A1..XFD104
- Anchor must be a column path like /{colSheetName}/col[L], go
- Sheet not found: {picSheetName}
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/c78aceaeff9d445a.
Report an issue: GitHub.