iOfficeAI/OfficeCLI · error · ArgumentException

Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D

Error message

Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D2:J18'.

What it means

Thrown when the chart 'anchor' property is present but fails to parse as an Excel cell or cell-range reference. The parser (TryParseCellRangeAnchor) expects the pattern ColRow or ColRow:ColRow (e.g. 'D2' or 'D2:J18'); anything else triggers this error. Note that providing anchor= alongside x/y/width/height first emits a warning (those are ignored), then this error fires if the anchor itself is malformed.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs:134

        // Position via TwoCellAnchor (shared by both standard and extended charts)
        // CONSISTENCY(ole-width-units): accept `anchor=D2:J18` as a cell
        // range (same grammar as OLE, shape, picture). When both
        // `anchor=<range>` and `x/y/width/height` are supplied, anchor
        // wins with a warning — matches shape/picture/OLE convention.
        int fromCol, fromRow, toCol, toRow;
        if (properties.TryGetValue("anchor", out var chartAnchorStr) && !string.IsNullOrWhiteSpace(chartAnchorStr))
        {
            // Non-short-circuit | on purpose: each ContainsKey marks the key
            // as handler-read in TrackingPropertyDictionary. With ||, finding
            // `width` skipped the x/y/height probes and they surfaced as a
            // false "UNSUPPORTED props" warning alongside this explicit one.
            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(chartAnchorStr, out var cxFrom, out var cyFrom, out var cxTo, out var cyTo))
                throw new ArgumentException($"Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D2:J18'.");
            fromCol = cxFrom;
            fromRow = cyFrom;
            if (cxTo < 0) { cxTo = fromCol + 8; cyTo = fromRow + 15; }
            toCol = cxTo;
            toRow = cyTo;
        }
        else
        {
            // CONSISTENCY(ole-width-units): accept cm/in/pt/EMU on chart x/y/width/height
            // (matches schema doc + OLE/picture/shape Add). Plain ints stay cell-count.
            fromCol = properties.TryGetValue("x", out var xStr) ? ParseAnchorOrigin(xStr, "x") : 0;
            fromRow = properties.TryGetValue("y", out var yStr) ? ParseAnchorOrigin(yStr, "y") : 0;
            toCol = properties.TryGetValue("width", out var wStr) ? fromCol + ParseAnchorDimension(wStr, "width") : fromCol + 8;
            toRow = properties.TryGetValue("height", out var hStr) ? fromRow + ParseAnchorDimension(hStr, "height") : fromRow + 15;
        }

        // Extended chart types (cx:chart) — funnel, treemap, sunburst, boxWhisker, histogram
        if (ChartExBuilder.IsExtendedChartType(chartType))

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Use a single-cell reference like 'D2' (the parser auto-extends to a default 8-col × 15-row rectangle).
  2. Use a colon-separated range like 'D2:J18' for an explicit rectangle.
  3. Remove the anchor property and use x=/y=/width=/height= instead for numeric cell-count positioning.
  4. Double-check there are no stray characters, commas, or R1C1-style notation.

Example fix

// before
add /Sheet1/chart --type chart --chartType bar --data "S1:1,2,3" --anchor "D2,J18"
// after
add /Sheet1/chart --type chart --chartType bar --data "S1:1,2,3" --anchor "D2:J18"
Defensive patterns

Strategy: validation

Validate before calling

// Validate chart anchor format before the add call
if (properties.TryGetValue("anchor", out var anchor) && !string.IsNullOrWhiteSpace(anchor))
{
    if (!System.Text.RegularExpressions.Regex.IsMatch(
            anchor, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase))
        throw new InvalidOperationException($"Invalid chart anchor '{anchor}'. Expected 'D2' or 'D2:J18'.");
}

Type guard

static bool IsValidCellRangeAnchor(string? s) =>
    !string.IsNullOrWhiteSpace(s) &&
    System.Text.RegularExpressions.Regex.IsMatch(
        s, @"^[A-Z]+\d+(:[A-Z]+\d+)?$", RegexOptions.IgnoreCase);

Try / catch

try { /* chart add with anchor */ }
catch (ArgumentException ex) when (ex.Message.StartsWith("Invalid anchor:"))
{
    Console.Error.WriteLine($"{ex.Message} Use 'D2' or 'D2:J18' format.");
}

Prevention

When it happens

Trigger: Setting properties["anchor"] to a value that does not match the regex ^([A-Z]+)(\d+)(?::([A-Z]+)(\d+))?$ (case-insensitive). Examples: 'D-2', 'col5', 'D2,J18', 'R1C1', 'A1:' (trailing colon). Also fires if the cell is outside the grid (A0, XFE1) since ValidateAnchorCell throws inside the parser.

Common situations: User copies an anchor from a different coordinate system (R1C1, pixel offsets, or PowerPoint slide coordinates). User accidentally pastes a comma-separated range instead of colon-separated. Trailing whitespace or a stray character from copy-paste.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/3713cc03ed7c9356. Report an issue: GitHub.