iOfficeAI/OfficeCLI · error · ArgumentException

Anchor sheet '{aSegs[0]}' must match source sheet '{sheetNam

Error message

Anchor sheet '{aSegs[0]}' must match source sheet '{sheetName}'

What it means

Thrown by the column-anchor resolver when the anchor's sheet segment does not equal the source sheet (aSegs[0] != sheetName). Column moves are within-sheet only, so the anchor column must belong to the same sheet being modified; a cross-sheet column anchor is rejected.

Source

Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.cs:438

        {
            var srcColLetter = colMatch.Groups[1].Value.ToUpperInvariant();
            var srcColIdx = ColumnNameToIndex(srcColLetter);

            // Resolve target. Default behavior (no position): append after the
            // last used column.
            int? targetColIdx = null;
            if (position?.Index.HasValue == true)
                targetColIdx = position.Index!.Value;
            else if (position?.Before != null || position?.After != null)
            {
                int FindAnchorColIdx(string anchorPath)
                {
                    var aSegs = anchorPath.TrimStart('/').Split('/', 2);
                    if (aSegs.Length < 2)
                        throw new ArgumentException(
                            $"Anchor must be a col path like /{sheetName}/col[L], got: {anchorPath}");
                    if (!aSegs[0].Equals(sheetName, StringComparison.OrdinalIgnoreCase))
                        throw new ArgumentException(
                            $"Anchor sheet '{aSegs[0]}' must match source sheet '{sheetName}'");
                    var am = Regex.Match(aSegs[1], @"^col\[([A-Za-z]+)\]$", RegexOptions.IgnoreCase);
                    if (!am.Success)
                        throw new ArgumentException(
                            $"Anchor must be a col path like /{sheetName}/col[L], got: {anchorPath}");
                    return ColumnNameToIndex(am.Groups[1].Value.ToUpperInvariant());
                }
                if (position.Before != null) targetColIdx = FindAnchorColIdx(position.Before);
                else targetColIdx = FindAnchorColIdx(position.After!) + 1;
            }
            else
            {
                // Append after last used column.
                int maxCol = 1;
                foreach (var r in sheetData.Elements<Row>())
                    foreach (var c in r.Elements<Cell>())
                        if (c.CellReference?.Value != null)
                            maxCol = Math.Max(maxCol, ColumnNameToIndex(ParseCellReference(c.CellReference.Value).Column));

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Set the anchor's sheet to the same sheet as the moved column.
  2. Build the anchor from the live sheetName variable.
  3. Use InsertPosition.AtIndex(n) to avoid sheet coupling.

Example fix

// before
h.Move("/Sheet1/col[B]", null, InsertPosition.BeforeElement("/Sheet2/col[A]"));
// after
h.Move("/Sheet1/col[B]", null, InsertPosition.BeforeElement("/Sheet1/col[A]"));
Defensive patterns

Strategy: validation

Validate before calling

var sheetName = sourcePath.TrimStart('/').Split('/', 2)[0];
foreach (var anchor in new[] { pos?.After, pos?.Before }.Where(a => a != null)!)
{
    var aSheet = anchor.TrimStart('/').Split('/', 2)[0];
    if (!aSheet.Equals(sheetName, StringComparison.OrdinalIgnoreCase))
        throw new InvalidOperationException($"Column anchor sheet '{aSheet}' must equal source '{sheetName}'");
}

Prevention

When it happens

Trigger: Moving columns in Sheet1 but passing InsertPosition.AfterElement("/Sheet2/col[A]"); anchor copied from another sheet; sheet rename leaving the anchor stale.

Common situations: Refactor that changed which sheet is operated on without updating the anchor; templated anchor string from a different sheet.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/28a21145cd3975fd. Report an issue: GitHub.