iOfficeAI/OfficeCLI · error · ArgumentException

Anchor must be a col path like /{sheetName}/col[L], got: {an

Error message

Anchor must be a col path like /{sheetName}/col[L], got: {anchorPath}

What it means

Thrown by the column-anchor resolver when a --before/--after anchor for a column move has no second segment (aSegs.Length < 2), i.e. the anchor is just "/Sheet1" with no '/col[L]'. Column anchors must be full element paths so the handler can map the letter to a column index.

Source

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

        // anchor must be col[L] in same sheet).
        var colMatch = Regex.Match(elementRef, @"^col\[([A-Za-z]+)\]$", RegexOptions.IgnoreCase);
        if (colMatch.Success)
        {
            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>())

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Provide the full anchor: "/<sheet>/col[<L>]" where L is a column letter (A, B, ...).
  2. Derive anchors from a verified column path.
  3. Use InsertPosition.AtIndex(n) with a numeric column index instead.

Example fix

// before
h.Move("/Sheet1/col[A]", null, InsertPosition.AfterElement("/Sheet1")); // no col segment
// after
h.Move("/Sheet1/col[A]", null, InsertPosition.AfterElement("/Sheet1/col[C]"));
Defensive patterns

Strategy: validation

Validate before calling

string AssertColAnchor(string anchor)
{
    var segs = anchor.TrimStart('/').Split('/', 2);
    if (segs.Length < 2)
        throw new ArgumentException($"Column anchor needs /sheet/col[L] form: '{anchor}'");
    return anchor;
}
var after = pos?.After is null ? null : AssertColAnchor(pos.After);
var before = pos?.Before is null ? null : AssertColAnchor(pos.Before);

Type guard

static bool IsFullElementPath(string p) =>
    p.TrimStart('/').Split('/', 2).Length >= 2;

Prevention

When it happens

Trigger: InsertPosition.BeforeElement("/Sheet1") used for a column move; bare sheet name passed as anchor; '/col[L]' suffix omitted.

Common situations: Reusing a sheet-level anchor for a column move; truncation when constructing the path; confusing sheet-reorder anchors with element anchors.

Related errors


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