{"record":{"id":"3079be7df7ef3998","repo":"iOfficeAI/OfficeCLI","slug":"swap-requires-element-paths-e-g-sheet1-row-1","errorCode":null,"errorMessage":"Swap requires element paths (e.g. /Sheet1/row[1])","messagePattern":"Swap requires element paths \\(e\\.g\\. /Sheet1/row\\[1\\]\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.cs","lineNumber":688,"sourceCode":"        {\n            row.RowIndex = newIdx;\n            foreach (var cell in row.Elements<Cell>())\n            {\n                if (cell.CellReference?.Value == null) continue;\n                var (col, _) = ParseCellReference(cell.CellReference.Value);\n                cell.CellReference = $\"{col}{newIdx}\";\n            }\n            newIdx++;\n        }\n    }\n\n    public (string NewPath1, string NewPath2) Swap(string path1, string path2)\n    {\n        // Parse both paths: /SheetName/row[N]\n        var seg1 = path1.TrimStart('/').Split('/', 2);\n        var seg2 = path2.TrimStart('/').Split('/', 2);\n        if (seg1.Length < 2 || seg2.Length < 2)\n            throw new ArgumentException(\"Swap requires element paths (e.g. /Sheet1/row[1])\");\n        if (seg1[0] != seg2[0])\n            throw new ArgumentException(\"Cannot swap elements across different sheets\");\n\n        var sheetName = seg1[0];\n        var worksheet = FindWorksheet(sheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {sheetName}\");\n        var sheetData = GetSheet(worksheet).GetFirstChild<SheetData>()\n            ?? throw new ArgumentException(\"Sheet has no data\");\n\n        var rowMatch1 = Regex.Match(seg1[1], @\"^row\\[(\\d+)\\]$\");\n        var rowMatch2 = Regex.Match(seg2[1], @\"^row\\[(\\d+)\\]$\");\n        if (!rowMatch1.Success || !rowMatch2.Success)\n            throw new ArgumentException(\"Swap only supports row[N] elements in Excel\");\n\n        var allRows = sheetData.Elements<Row>().ToList();\n        var idx1 = int.Parse(rowMatch1.Groups[1].Value);\n        var idx2 = int.Parse(rowMatch2.Groups[1].Value);\n        var row1 = (idx1 >= 1 && idx1 <= allRows.Count ? allRows[idx1 - 1] : null)","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.cs#L670-L706","documentation":"Thrown by Swap when one of the two paths has no second segment after splitting (seg1 or seg2 Length < 2), i.e. a path like \"/Sheet1\" without the '/row[N]' part. Swap exchanges two row elements, so both arguments must be full element paths.","triggerScenarios":"Swap(\"/Sheet1\", \"/Sheet1/row[2]\"); a path truncated to just the sheet; passing a sheet-level path where a row path is required.","commonSituations":"Building swap args from a sheet name instead of a row path; partial path construction; confusing Swap (element exchange) with sheet reorder.","solutions":["Pass full row paths for both arguments: \"/<sheet>/row[<N>]\".","Construct swap paths from verified row nodes, not sheet nodes.","If you meant to reorder sheets, use Move on a sheet-level path instead."],"exampleFix":"// before\nh.Swap(\"/Sheet1\", \"/Sheet1/row[2]\"); // first arg has no element segment\n// after\nh.Swap(\"/Sheet1/row[1]\", \"/Sheet1/row[2]\");","handlingStrategy":"validation","validationCode":"static bool IsElementPath(string p) => p.TrimStart('/').Split('/', 2).Length >= 2;\nif (!IsElementPath(path1) || !IsElementPath(path2))\n    throw new ArgumentException(\"Swap requires full /sheet/row[N] paths for both arguments\");","typeGuard":"static bool IsSwapCandidate(string p)\n{\n    var segs = p.TrimStart('/').Split('/', 2);\n    return segs.Length >= 2 && System.Text.RegularExpressions.Regex.IsMatch(segs[1], @\"^row\\[\\d+\\]$\");\n}","tryCatchPattern":null,"preventionTips":["Pass full /sheet/row[N] paths to Swap, never sheet-only paths.","Build swap args from verified row nodes.","Use Move for sheet reordering, not Swap."],"tags":["excel","openxml","swap","malformed-path","validation"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}