{"record":{"id":"a6c4acaa3ae0a971","repo":"iOfficeAI/OfficeCLI","slug":"invalid-anchor-oleanchorstr-expected-e-g-b","errorCode":null,"errorMessage":"Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:E6'.","messagePattern":"Invalid anchor: '(.+?)'\\. Expected e\\.g\\. 'B2' or 'B2:E6'\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs","lineNumber":146,"sourceCode":"        int oleFromCol, oleFromRow, oleToCol, oleToRow;\n        // FromMarker offsets are always zero (anchor starts at cell boundary);\n        // ToMarker offsets carry the sub-cell EMU remainder for unit-qualified\n        // width/height inputs, preserving round-trip precision.\n        const long oleFromColOff = 0, oleFromRowOff = 0;\n        long oleToColOff = 0, oleToRowOff = 0;\n        if (properties.TryGetValue(\"anchor\", out var oleAnchorStr) && !string.IsNullOrWhiteSpace(oleAnchorStr))\n        {\n            // CONSISTENCY(ole-width-units): anchor= defines the full\n            // rectangle (start+end cells), so width/height on the same\n            // Add call would be ambiguous and are silently dropped.\n            // Warn loudly rather than fail, so existing scripts keep\n            // working but users notice the dropped value.\n            if (properties.ContainsKey(\"width\") | properties.ContainsKey(\"height\"))\n                Console.Error.WriteLine(\n                    \"Warning: 'width'/'height' are ignored when 'anchor' is provided (anchor defines the full rectangle).\");\n            var m = Regex.Match(oleAnchorStr, @\"^([A-Z]+)(\\d+)(?::([A-Z]+)(\\d+))?$\", RegexOptions.IgnoreCase);\n            if (!m.Success)\n                throw new ArgumentException($\"Invalid anchor: '{oleAnchorStr}'. Expected e.g. 'B2' or 'B2:E6'.\");\n            // CONSISTENCY(xdr-coords): XDR ColumnId/RowId are 0-based;\n            // ColumnNameToIndex returns 1-based, so subtract 1 here.\n            oleFromCol = ColumnNameToIndex(m.Groups[1].Value) - 1;\n            oleFromRow = int.Parse(m.Groups[2].Value) - 1;\n            ValidateAnchorCell(oleFromCol, oleFromRow, oleAnchorStr.Split(':')[0]);\n            if (m.Groups[3].Success)\n            {\n                oleToCol = ColumnNameToIndex(m.Groups[3].Value) - 1;\n                oleToRow = int.Parse(m.Groups[4].Value) - 1;\n                ValidateAnchorCell(oleToCol, oleToRow, oleAnchorStr.Split(':')[1]);\n                NormalizeAnchorRect(ref oleFromCol, ref oleFromRow, ref oleToCol, ref oleToRow);\n            }\n            else\n            {\n                oleToCol = oleFromCol + 2;\n                oleToRow = oleFromRow + 3;\n            }\n        }","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs#L128-L164","documentation":"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.","triggerScenarios":"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).","commonSituations":"User copies pixel-based or R1C1 coordinates. User uses a comma instead of a colon for ranges. Copy-paste introduces invisible characters.","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."],"exampleFix":"// before\nadd /Sheet1 --type ole --src obj.xlsx --anchor \"B2,E6\"\n// after\nadd /Sheet1 --type ole --src obj.xlsx --anchor \"B2:E6\"","handlingStrategy":"validation","validationCode":"// Validate OLE anchor format before the add call\nif (properties.TryGetValue(\"anchor\", out var oleAnchor) && !string.IsNullOrWhiteSpace(oleAnchor))\n{\n    if (!System.Text.RegularExpressions.Regex.IsMatch(\n            oleAnchor, @\"^[A-Z]+\\d+(:[A-Z]+\\d+)?$\", RegexOptions.IgnoreCase))\n        throw new InvalidOperationException(\n            $\"Invalid OLE anchor '{oleAnchor}'. Expected 'B2' or 'B2:E6'.\");\n}","typeGuard":"static bool IsValidOleAnchor(string? s) =>\n    !string.IsNullOrWhiteSpace(s) &&\n    System.Text.RegularExpressions.Regex.IsMatch(\n        s, @\"^[A-Z]+\\d+(:[A-Z]+\\d+)?$\", RegexOptions.IgnoreCase);","tryCatchPattern":"try { handler.AddOle(parentPath, properties); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Invalid anchor:\"))\n{\n    Console.Error.WriteLine($\"{ex.Message} Use 'B2' or 'B2:E6' format.\");\n}","preventionTips":["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=."],"tags":["excel","ole","anchor","cell-reference","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}