iOfficeAI/OfficeCLI · error · ArgumentException
After anchor not found: {position.After}
Error message
After anchor not found: {position.After} What it means
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.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.cs:199
// supports --index / --after /Sheet2 / --before /Sheet3.
var workbook = GetWorkbook();
var sheets = workbook.GetFirstChild<Sheets>()
?? throw new InvalidOperationException("Workbook has no sheets element");
var sheetEl = sheets.Elements<Sheet>().FirstOrDefault(s =>
string.Equals(s.Name?.Value, sheetName, StringComparison.OrdinalIgnoreCase))
?? throw new ArgumentException($"Sheet not found: {sheetName}");
// Resolve after/before anchor BEFORE removing sheetEl.
static string ExtractAnchorSheetName(string raw) =>
(raw.StartsWith("/") ? raw[1..] : raw).Split('/', 2)[0];
Sheet? afterAnchor = null, beforeAnchor = null;
if (position?.After != null)
{
var anchorName = ExtractAnchorSheetName(position.After);
afterAnchor = sheets.Elements<Sheet>().FirstOrDefault(s =>
string.Equals(s.Name?.Value, anchorName, StringComparison.OrdinalIgnoreCase))
?? throw new ArgumentException($"After anchor not found: {position.After}");
}
else if (position?.Before != null)
{
var anchorName = ExtractAnchorSheetName(position.Before);
beforeAnchor = sheets.Elements<Sheet>().FirstOrDefault(s =>
string.Equals(s.Name?.Value, anchorName, StringComparison.OrdinalIgnoreCase))
?? throw new ArgumentException($"Before anchor not found: {position.Before}");
}
else if (index == null)
{
throw new ArgumentException("One of --index, --after, or --before is required when moving a sheet");
}
// Self-move guard: moving a sheet after/before itself is a no-op.
// Removing first detaches sheetEl, then InsertAfterSelf/InsertBeforeSelf
// throws "parent is null" and the sheet is lost (data loss).
if (ReferenceEquals(afterAnchor, sheetEl) || ReferenceEquals(beforeAnchor, sheetEl))
return $"/{sheetName}";View on GitHub (pinned to 1ced45e900)
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.
Example fix
// before
h.Move("/Sheet1", null, InsertPosition.AfterElement("/SheetX")); // SheetX missing
// after
h.Move("/Sheet1", null, InsertPosition.AfterElement("/Sheet2")); // Sheet2 exists Defensive patterns
Strategy: validation
Validate before calling
string AnchorSheet(string raw) => (raw.StartsWith("/") ? raw[1..] : raw).Split('/', 2)[0];
var sheets = handler.Get("/", depth: 1).Children.Select(c => c.Name).ToList();
if (pos?.After is { } a && !sheets.Any(s => s.Equals(AnchorSheet(a), StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException($"--after anchor sheet '{a}' does not exist"); Try / catch
try { handler.Move("/Sheet1", null, InsertPosition.AfterElement(anchor)); }
catch (ArgumentException ex) when (ex.Message.StartsWith("After anchor not found"))
{ /* prompt for a valid anchor sheet from the live list */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Before anchor not found: {position.Before}
- Anchor row {anchorRowIdx} not found in {targetSheetName}
- One of --index, --after, or --before is required when moving
- Target sheet not found: {tgtSegments[0]}
- Row {rowIdx} not found
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/aea21a677fe94b64.
Report an issue: GitHub.