{"record":{"id":"bc6336189de8c244","repo":"iOfficeAI/OfficeCLI","slug":"invalid-anchor-shpanchorstr-expected-e-g-b","errorCode":null,"errorMessage":"Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:F7'.","messagePattern":"Invalid anchor: '(.+?)'\\. Expected e\\.g\\. 'B2' or 'B2:F7'\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs","lineNumber":613,"sourceCode":"                // rectangle (B2:C3) so the shape has a visible extent.\n                // Using identical from/to markers produces a\n                // zero-width/height invisible shape in Excel.\n                if (TryParseCellRangeAnchor(refTrim, out var rc, out var rr, out _, out _))\n                    refTrim = $\"{refTrim}:{IndexToColumnName(rc + 2)}{rr + 2}\";\n                else\n                    refTrim = $\"{refTrim}:{refTrim}\";\n            }\n            properties[\"anchor\"] = refTrim;\n        }\n        int sx, sy, sw, sh;\n        if (properties.TryGetValue(\"anchor\", out var shpAnchorStr) && !string.IsNullOrWhiteSpace(shpAnchorStr))\n        {\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(shpAnchorStr, out var sxFrom, out var syFrom, out var sxTo, out var syTo))\n                throw new ArgumentException($\"Invalid anchor: '{shpAnchorStr}'. Expected e.g. 'B2' or 'B2:F7'.\");\n            sx = sxFrom;\n            sy = syFrom;\n            if (sxTo < 0) { sxTo = sx + 4; syTo = sy + 2; }\n            sw = sxTo - sx;\n            sh = syTo - sy;\n        }\n        else\n        {\n            (sx, sy, sw, sh) = ParseAnchorBounds(properties, \"1\", \"1\", \"5\", \"3\");\n        }\n        // Clamp the derived TwoCellAnchor span to Excel's grid so an\n        // x/y/width/height that walks the TO marker past the ceiling ends at the\n        // grid edge (what real Excel does) instead of being written out of range\n        // into a file Excel refuses to open. FROM out of grid still throws.\n        {\n            var (shpToCol, shpToRow) = ClampAnchorSpan(sx, sy, sx + sw, sy + sh,\n                shpAnchorStr ?? $\"x={sx},y={sy},width={sw},height={sh}\");\n            sw = shpToCol - sx;","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs#L595-L631","documentation":"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.","triggerScenarios":"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=.","commonSituations":"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.","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."],"exampleFix":"// before\nadd ./book.xlsx /Sheet1 shape --type rectangle --prop anchor=100,100,200,80\n// after\nadd ./book.xlsx /Sheet1 shape --type rectangle --prop anchor=B2:F7","handlingStrategy":"validation","validationCode":"// Use the same parser the handler uses to pre-validate the anchor.\nif (!ExcelHandler.TryParseCellRangeAnchor(anchorStr,\n        out var fc, out var fr, out var tc, out var tr))\n    throw new InvalidOperationException(\n        $\"anchor '{anchorStr}' must be like 'B2' or 'B2:F7'\");","typeGuard":"static bool IsValidCellAnchor(string? s)\n    => System.Text.RegularExpressions.Regex.IsMatch(\n        s ?? \"\", @\"^[A-Za-z]{1,3}\\d+(:[A-Za-z]{1,3}\\d+)?$\");","tryCatchPattern":"try { handler.Add(...); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Invalid anchor\"))\n{\n    // prompt the user for a corrected A1 range\n}","preventionTips":["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."],"tags":["excel","anchor","cell-reference","input-validation","drawing"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}