{"record":{"id":"41c1cf7275069124","repo":"iOfficeAI/OfficeCLI","slug":"anchor-sheet-asegs-0-must-match-target-sheet-41c1cf","errorCode":null,"errorMessage":"Anchor sheet '{aSegs[0]}' must match target sheet '{colSheetName}'","messagePattern":"Anchor sheet '(.+?)' must match target sheet '(.+?)'","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":1050,"sourceCode":"        var colSegments = parentPath.TrimStart('/').Split('/', 2);\n        var colSheetName = colSegments[0];\n        var colWorksheet = FindWorksheet(colSheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {colSheetName}\");\n\n        // Resolve --before / --after anchors, mirroring AddRow. Anchor must\n        // be /<sheetName>/col[L] in the same sheet; --before takes the\n        // anchor's slot, --after lands one column to the right.\n        int? index = position?.Index;\n        if (index == null && position != null && (position.After != null || position.Before != null))\n        {\n            int FindAnchorColIndex(string anchorPath)\n            {\n                var aSegs = anchorPath.TrimStart('/').Split('/', 2);\n                if (aSegs.Length < 2)\n                    throw new ArgumentException(\n                        $\"Anchor must be a column path like /{colSheetName}/col[L], got: {anchorPath}\");\n                if (!aSegs[0].Equals(colSheetName, StringComparison.OrdinalIgnoreCase))\n                    throw new ArgumentException(\n                        $\"Anchor sheet '{aSegs[0]}' must match target sheet '{colSheetName}'\");\n                var am = Regex.Match(aSegs[1], @\"^col\\[([A-Za-z]+)\\]$\", RegexOptions.IgnoreCase);\n                if (!am.Success)\n                    throw new ArgumentException(\n                        $\"Anchor must be a column path like /{colSheetName}/col[L], got: {anchorPath}\");\n                return ColumnNameToIndex(am.Groups[1].Value.ToUpperInvariant());\n            }\n            if (position.Before != null) index = FindAnchorColIndex(position.Before);\n            else index = FindAnchorColIndex(position.After!) + 1;\n        }\n\n        // Determine insert column: index (1-based) or name/letter from properties\n        // CONSISTENCY(col-letter-prop): accept col=, letter=, column= as aliases of name=\n        // matching how `colbreak` (case \"colbreak\" above) accepts col/column/index.\n        string insertColName;\n        string? colLetterProp = null;\n        if (properties.TryGetValue(\"name\", out var colNameProp) && !string.IsNullOrEmpty(colNameProp))\n            colLetterProp = colNameProp;","sourceCodeStart":1032,"sourceCodeEnd":1068,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L1032-L1068","documentation":"Thrown by AddCol when resolving a --before/--after anchor for a column insertion. The anchor path's sheet segment (aSegs[0]) does not match the target sheet name (colSheetName) that the column is being added to. The comparison is OrdinalIgnoreCase, so it is purely a name mismatch, not a casing issue. This guard prevents inserting into one sheet using an anchor that lives in a different sheet, which would silently produce a wrong column index.","triggerScenarios":"Calling Add with type=col on /TargetSheet and an InsertPosition whose Before or After is a path like /OtherSheet/col[C] where OtherSheet != TargetSheet. For example: parentPath=\"/Sheet1\", position.Before=\"/Sheet2/col[B\". The local function FindAnchorColIndex is only invoked when position.Index is null and Before/After is set.","commonSituations":"Script copies an anchor path from a different sheet's dump output and reuses it verbatim. Renaming a sheet after copying anchor paths. Mixing up sheet variables when building the position object across two sheets in the same script.","solutions":["Make the anchor path's sheet segment identical to the target sheet: use /<colSheetName>/col[L] for both --before and --after.","If you intend to anchor relative to a column in another sheet, insert the column there instead, or compute the absolute numeric index and pass it via position.Index to bypass anchor resolution entirely.","Verify the sheet name spelling against the workbook with a Get on /SheetName before constructing the position."],"exampleFix":"// before\nvar pos = new InsertPosition { Before = \"/Sheet2/col[B]\" };\nhandler.Add(\"/Sheet1\", \"col\", pos, props);\n\n// after\nvar pos = new InsertPosition { Before = \"/Sheet1/col[B]\" };\nhandler.Add(\"/Sheet1\", \"col\", pos, props);","handlingStrategy":"validation","validationCode":"string targetSheet = \"Sheet1\";\nstring anchor = \"/Sheet1/col[B]\";\nvar aSegs = anchor.TrimStart('/').Split('/', 2);\nif (aSegs.Length < 2 || !aSegs[0].Equals(targetSheet, StringComparison.OrdinalIgnoreCase))\n    throw new InvalidOperationException($\"Anchor sheet must be {targetSheet}\");\nhandler.Add(\"/\" + targetSheet, \"col\", new InsertPosition { Before = anchor }, props);","typeGuard":"static bool AnchorTargetsSheet(string anchorPath, string targetSheet)\n{\n    var segs = anchorPath.TrimStart('/').Split('/', 2);\n    return segs.Length >= 2\n        && segs[0].Equals(targetSheet, StringComparison.OrdinalIgnoreCase)\n        && System.Text.RegularExpressions.Regex.IsMatch(segs[1], @\"^col\\[([A-Za-z]+)\\]$\", System.Text.RegularExpressions.RegexOptions.IgnoreCase);\n}","tryCatchPattern":null,"preventionTips":["Derive the anchor path from the same sheet variable used as the target sheet.","Prefer position.Index (numeric) over Before/After when you already know the column number, to bypass anchor resolution entirely.","Validate the anchor path format with the type guard before constructing the InsertPosition."],"tags":["excel","ooxml","add-col","anchor","path-validation","argument"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}