{"record":{"id":"aea21a677fe94b64","repo":"iOfficeAI/OfficeCLI","slug":"after-anchor-not-found-position-after","errorCode":null,"errorMessage":"After anchor not found: {position.After}","messagePattern":"After anchor not found: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.cs","lineNumber":199,"sourceCode":"            // supports --index / --after /Sheet2 / --before /Sheet3.\n            var workbook = GetWorkbook();\n            var sheets = workbook.GetFirstChild<Sheets>()\n                ?? throw new InvalidOperationException(\"Workbook has no sheets element\");\n            var sheetEl = sheets.Elements<Sheet>().FirstOrDefault(s =>\n                string.Equals(s.Name?.Value, sheetName, StringComparison.OrdinalIgnoreCase))\n                ?? throw new ArgumentException($\"Sheet not found: {sheetName}\");\n\n            // Resolve after/before anchor BEFORE removing sheetEl.\n            static string ExtractAnchorSheetName(string raw) =>\n                (raw.StartsWith(\"/\") ? raw[1..] : raw).Split('/', 2)[0];\n\n            Sheet? afterAnchor = null, beforeAnchor = null;\n            if (position?.After != null)\n            {\n                var anchorName = ExtractAnchorSheetName(position.After);\n                afterAnchor = sheets.Elements<Sheet>().FirstOrDefault(s =>\n                    string.Equals(s.Name?.Value, anchorName, StringComparison.OrdinalIgnoreCase))\n                    ?? throw new ArgumentException($\"After anchor not found: {position.After}\");\n            }\n            else if (position?.Before != null)\n            {\n                var anchorName = ExtractAnchorSheetName(position.Before);\n                beforeAnchor = sheets.Elements<Sheet>().FirstOrDefault(s =>\n                    string.Equals(s.Name?.Value, anchorName, StringComparison.OrdinalIgnoreCase))\n                    ?? throw new ArgumentException($\"Before anchor not found: {position.Before}\");\n            }\n            else if (index == null)\n            {\n                throw new ArgumentException(\"One of --index, --after, or --before is required when moving a sheet\");\n            }\n\n            // Self-move guard: moving a sheet after/before itself is a no-op.\n            // Removing first detaches sheetEl, then InsertAfterSelf/InsertBeforeSelf\n            // throws \"parent is null\" and the sheet is lost (data loss).\n            if (ReferenceEquals(afterAnchor, sheetEl) || ReferenceEquals(beforeAnchor, sheetEl))\n                return $\"/{sheetName}\";","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.cs#L181-L217","documentation":"Thrown when moving a whole sheet with --after where the anchor sheet named in position.After is not present in the <sheets> catalog (ExtractAnchorSheetName + OrdinalIgnoreCase lookup failed). The reorder needs a concrete sibling to insert after, so an unknown anchor aborts the move.","triggerScenarios":"Move(\"/Sheet1\", null, InsertPosition.AfterElement(\"/Gone\")) where 'Gone' is not a sheet; typo in the anchor name; anchor referencing a sheet from a different workbook.","commonSituations":"Anchor sheet deleted/renamed since the path was captured; copy-paste of a stale path; case the user assumed is supported but the name is simply wrong.","solutions":["Confirm the anchor sheet exists in the current workbook before calling Move.","Use InsertPosition.AtIndex(n) if you only need an absolute position.","Prefer InsertPosition.AfterElement(\"/<existingSheet>\") with a verified name."],"exampleFix":"// before\nh.Move(\"/Sheet1\", null, InsertPosition.AfterElement(\"/SheetX\")); // SheetX missing\n// after\nh.Move(\"/Sheet1\", null, InsertPosition.AfterElement(\"/Sheet2\")); // Sheet2 exists","handlingStrategy":"validation","validationCode":"string AnchorSheet(string raw) => (raw.StartsWith(\"/\") ? raw[1..] : raw).Split('/', 2)[0];\nvar sheets = handler.Get(\"/\", depth: 1).Children.Select(c => c.Name).ToList();\nif (pos?.After is { } a && !sheets.Any(s => s.Equals(AnchorSheet(a), StringComparison.OrdinalIgnoreCase)))\n    throw new InvalidOperationException($\"--after anchor sheet '{a}' does not exist\");","typeGuard":null,"tryCatchPattern":"try { handler.Move(\"/Sheet1\", null, InsertPosition.AfterElement(anchor)); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"After anchor not found\"))\n{ /* prompt for a valid anchor sheet from the live list */ }","preventionTips":["Validate the anchor sheet against handler.Get(\"/\", depth:1) before calling.","Prefer InsertPosition.AtIndex(n) when you do not need a named anchor.","Capture anchor names from the current workbook, not saved state."],"tags":["excel","openxml","move","sheet-reorder","anchor","not-found"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}