{"record":{"id":"9708c4f9048015eb","repo":"iOfficeAI/OfficeCLI","slug":"parent-path-must-be-sheetname-cellref-for-adding","errorCode":null,"errorMessage":"Parent path must be /SheetName/CellRef for adding a run","messagePattern":"Parent path must be /SheetName/CellRef for adding a run","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":1203,"sourceCode":"            {\n                newCol.Collapsed = addColCollapsed.Equals(\"true\", StringComparison.OrdinalIgnoreCase)\n                    || addColCollapsed == \"1\" || addColCollapsed.Equals(\"yes\", StringComparison.OrdinalIgnoreCase);\n            }\n            if (existingCol == null)\n                columns.AppendChild(newCol);\n        }\n\n        SaveWorksheet(colWorksheet);\n        return $\"/{colSheetName}/col[{insertColName}]\";\n    }\n\n    private string AddRun(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)\n    {\n        var index = position?.Index;\n        // Add a rich text run to a cell: parentPath = /SheetName/CellRef\n        var runSegments = parentPath.TrimStart('/').Split('/', 2);\n        if (runSegments.Length < 2)\n            throw new ArgumentException(\"Parent path must be /SheetName/CellRef for adding a run\");\n        var runSheetName = runSegments[0];\n        var runCellRef = runSegments[1].ToUpperInvariant();\n        var runWorksheet = FindWorksheet(runSheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {runSheetName}\");\n        var runSheetData = GetSheet(runWorksheet).GetFirstChild<SheetData>()\n            ?? GetSheet(runWorksheet).AppendChild(new SheetData());\n        var runCell = FindOrCreateCell(runSheetData, runCellRef);\n\n        var runWbPart = _doc.WorkbookPart\n            ?? throw new InvalidOperationException(\"Workbook not found\");\n        var runSstPart = runWbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()\n            ?? runWbPart.AddNewPart<SharedStringTablePart>();\n        SharedStringTable runSst;\n        if (runSstPart.SharedStringTable != null)\n            runSst = runSstPart.SharedStringTable;\n        else\n        {\n            runSst = new SharedStringTable();","sourceCodeStart":1185,"sourceCodeEnd":1221,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L1185-L1221","documentation":"Thrown by AddRun when the parentPath does not contain at least two segments after trimming the leading slash. A rich-text run must be attached to a specific cell, so the path must be /SheetName/CellRef (e.g. /Sheet1/A1). Splitting on '/' with a limit of 2 yields fewer than 2 segments only when the path is just a sheet name with no cell reference.","triggerScenarios":"Calling Add with type=run (or richtext routed here) and parentPath=\"/Sheet1\" or parentPath=\"/Sheet1/\". Also triggered by a bare path like \"Sheet1\" with no cell. Any path whose second segment is empty after the split still passes (Length is 2), so this specific throw needs a path that is a single segment.","commonSituations":"User omits the cell reference, intending to add a run to a whole sheet or the first cell. Passing a sheet-scoped path that was copied from a sheet-level command (like add col or add rowbreak). Reusing a parentPath variable built for a different element type.","solutions":["Append the target cell reference to the path: /SheetName/A1.","If you meant to set the whole cell as rich text (not add a run to an existing cell), use type=richtext with runs=... on a cell path instead.","Construct the path from a verified sheet name and a valid A1-style cell reference."],"exampleFix":"// before\nhandler.Add(\"/Sheet1\", \"run\", pos, props);\n\n// after\nhandler.Add(\"/Sheet1/A1\", \"run\", pos, props);","handlingStrategy":"validation","validationCode":"string parent = \"/Sheet1/A1\";\nvar segs = parent.TrimStart('/').Split('/', 2);\nif (segs.Length < 2 || string.IsNullOrEmpty(segs[1]))\n    throw new InvalidOperationException(\"Run parent path must be /Sheet/CellRef\");\nhandler.Add(parent, \"run\", pos, props);","typeGuard":"static bool IsCellPath(string path)\n{\n    var segs = path.TrimStart('/').Split('/', 2);\n    return segs.Length >= 2 && !string.IsNullOrEmpty(segs[1])\n        && System.Text.RegularExpressions.Regex.IsMatch(segs[1], @\"^[A-Za-z]+[0-9]+$\");\n}","tryCatchPattern":null,"preventionTips":["Always build run paths from a sheet name plus a cell reference constant.","Reuse a helper that formats /{sheet}/{cell} so a segment is never dropped.","Prefer type=richtext with runs= on a cell path for whole-cell rich text."],"tags":["excel","ooxml","add-run","richtext","path-validation","argument"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}