{"record":{"id":"3713cc03ed7c9356","repo":"iOfficeAI/OfficeCLI","slug":"invalid-anchor-chartanchorstr-expected-e-g","errorCode":null,"errorMessage":"Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D2:J18'.","messagePattern":"Invalid anchor: '(.+?)'\\. Expected e\\.g\\. 'D2' or 'D2:J18'\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs","lineNumber":134,"sourceCode":"\n        // Position via TwoCellAnchor (shared by both standard and extended charts)\n        // CONSISTENCY(ole-width-units): accept `anchor=D2:J18` as a cell\n        // range (same grammar as OLE, shape, picture). When both\n        // `anchor=<range>` and `x/y/width/height` are supplied, anchor\n        // wins with a warning — matches shape/picture/OLE convention.\n        int fromCol, fromRow, toCol, toRow;\n        if (properties.TryGetValue(\"anchor\", out var chartAnchorStr) && !string.IsNullOrWhiteSpace(chartAnchorStr))\n        {\n            // Non-short-circuit | on purpose: each ContainsKey marks the key\n            // as handler-read in TrackingPropertyDictionary. With ||, finding\n            // `width` skipped the x/y/height probes and they surfaced as a\n            // false \"UNSUPPORTED props\" warning alongside this explicit one.\n            if (properties.ContainsKey(\"width\") | properties.ContainsKey(\"height\")\n                | properties.ContainsKey(\"x\") | properties.ContainsKey(\"y\"))\n                Console.Error.WriteLine(\n                    \"Warning: 'x'/'y'/'width'/'height' are ignored when 'anchor' is provided (anchor defines the full rectangle).\");\n            if (!TryParseCellRangeAnchor(chartAnchorStr, out var cxFrom, out var cyFrom, out var cxTo, out var cyTo))\n                throw new ArgumentException($\"Invalid anchor: '{chartAnchorStr}'. Expected e.g. 'D2' or 'D2:J18'.\");\n            fromCol = cxFrom;\n            fromRow = cyFrom;\n            if (cxTo < 0) { cxTo = fromCol + 8; cyTo = fromRow + 15; }\n            toCol = cxTo;\n            toRow = cyTo;\n        }\n        else\n        {\n            // CONSISTENCY(ole-width-units): accept cm/in/pt/EMU on chart x/y/width/height\n            // (matches schema doc + OLE/picture/shape Add). Plain ints stay cell-count.\n            fromCol = properties.TryGetValue(\"x\", out var xStr) ? ParseAnchorOrigin(xStr, \"x\") : 0;\n            fromRow = properties.TryGetValue(\"y\", out var yStr) ? ParseAnchorOrigin(yStr, \"y\") : 0;\n            toCol = properties.TryGetValue(\"width\", out var wStr) ? fromCol + ParseAnchorDimension(wStr, \"width\") : fromCol + 8;\n            toRow = properties.TryGetValue(\"height\", out var hStr) ? fromRow + ParseAnchorDimension(hStr, \"height\") : fromRow + 15;\n        }\n\n        // Extended chart types (cx:chart) — funnel, treemap, sunburst, boxWhisker, histogram\n        if (ChartExBuilder.IsExtendedChartType(chartType))","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Chart.cs#L116-L152","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use a single-cell reference like 'D2' (the parser auto-extends to a default 8-col × 15-row rectangle).","Use a colon-separated range like 'D2:J18' for an explicit rectangle.","Remove the anchor property and use x=/y=/width=/height= instead for numeric cell-count positioning.","Double-check there are no stray characters, commas, or R1C1-style notation."],"exampleFix":"// before\nadd /Sheet1/chart --type chart --chartType bar --data \"S1:1,2,3\" --anchor \"D2,J18\"\n// after\nadd /Sheet1/chart --type chart --chartType bar --data \"S1:1,2,3\" --anchor \"D2:J18\"","handlingStrategy":"validation","validationCode":"// Validate chart anchor format before the add call\nif (properties.TryGetValue(\"anchor\", out var anchor) && !string.IsNullOrWhiteSpace(anchor))\n{\n    if (!System.Text.RegularExpressions.Regex.IsMatch(\n            anchor, @\"^[A-Z]+\\d+(:[A-Z]+\\d+)?$\", RegexOptions.IgnoreCase))\n        throw new InvalidOperationException($\"Invalid chart anchor '{anchor}'. Expected 'D2' or 'D2:J18'.\");\n}","typeGuard":"static bool IsValidCellRangeAnchor(string? s) =>\n    !string.IsNullOrWhiteSpace(s) &&\n    System.Text.RegularExpressions.Regex.IsMatch(\n        s, @\"^[A-Z]+\\d+(:[A-Z]+\\d+)?$\", RegexOptions.IgnoreCase);","tryCatchPattern":"try { /* chart add with anchor */ }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Invalid anchor:\"))\n{\n    Console.Error.WriteLine($\"{ex.Message} Use 'D2' or 'D2:J18' format.\");\n}","preventionTips":["Use only A1-style cell references (letters for columns, digits for rows) for anchor=.","Separate range endpoints with a colon (:), not a comma or dash.","Pre-validate anchor strings with a regex before passing to the handler.","Avoid R1C1 notation, pixel offsets, and slide-style coordinates."],"tags":["excel","chart","anchor","cell-reference","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}