{"record":{"id":"e5948367364fbcce","repo":"iOfficeAI/OfficeCLI","slug":"sheet-not-found-cellsheetname","errorCode":null,"errorMessage":"Sheet not found: {cellSheetName}","messagePattern":"Sheet not found: (.+?)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs","lineNumber":333,"sourceCode":"        // by a prior cell op on the same sheet, it now lacks the new row\n        // — a subsequent AddCell at the same row index would cache-miss\n        // and create a duplicate <x:row r=\"N\">, producing an\n        // Excel-rejected file. Invalidate the cache to force a rescan.\n        InvalidateRowIndex(sheetData);\n\n        if (needsShift)\n            DeleteCalcChainIfPresent();\n        SaveWorksheet(worksheet);\n        return $\"/{sheetName}/row[{rowIdx}]\";\n    }\n\n    private string AddCell(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)\n    {\n        var index = position?.Index;\n        var cellSegments = parentPath.TrimStart('/').Split('/', 2);\n        var cellSheetName = cellSegments[0];\n        var cellWorksheet = FindWorksheet(cellSheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {cellSheetName}\");\n        var cellSheetData = GetSheet(cellWorksheet).GetFirstChild<SheetData>()\n            ?? GetSheet(cellWorksheet).AppendChild(new SheetData());\n\n        // R7-1: if path tail is a cell-ref (e.g. /Sheet1/Z99), treat it\n        // as the target address — equivalent to --prop ref=Z99. Parity\n        // with the `comment` case below which already does this.\n        string? cellRefFromPath = null;\n        if (cellSegments.Length > 1 && Regex.IsMatch(cellSegments[1], @\"^[A-Z]+\\d+$\", RegexOptions.IgnoreCase))\n            cellRefFromPath = cellSegments[1].ToUpperInvariant();\n        // R10-2: also honor a cell[<ref>] path tail (e.g. /Sheet1/cell[C5]) so\n        // `add /Sheet1/cell[C5] cell` lands at C5 instead of silently snapping\n        // to A1. Mirrors the bare-cellref tail above and the row[N] tail below;\n        // without it, \"cell[C5]\" matched neither regex and auto-assign chose A1.\n        else if (cellSegments.Length > 1)\n        {\n            var cellPathMatch = Regex.Match(cellSegments[1], @\"^cell\\[([A-Z]+\\d+)\\]$\", RegexOptions.IgnoreCase);\n            if (cellPathMatch.Success)\n                cellRefFromPath = cellPathMatch.Groups[1].Value.ToUpperInvariant();","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Cells.cs#L315-L351","documentation":"AddCell resolves the parent path's first segment as the worksheet name and looks it up via FindWorksheet. If no worksheet by that name exists (case-insensitive), it throws before touching SheetData. This prevents writing cells into a non-existent sheet, which would otherwise create an orphan <c> or fail silently.","triggerScenarios":"Add(\"/NonExistent/A1\",\"cell\",pos,props); Add(\"/Sheet1/A1\",\"cell\",...) on a workbook where the sheet was renamed/deleted; a typo in the sheet name; a sheet path using an index that ResolveSheetIndexInPath could not map.","commonSituations":"Hardcoded sheet names that drift after a rename; replaying a batch recorded against one workbook onto a different workbook whose sheets differ; case mismatch that looks identical but the sheet genuinely does not exist (note FindWorksheet is case-insensitive, so genuine case differences would NOT throw here).","solutions":["List sheets first (Get/Query on the workbook root) and confirm the exact name exists before adding cells.","If the sheet should exist, create it with Add(\"/\",\"sheet\",null,{[\"name\"]=sheetName}) before adding cells.","Check for typos and stray whitespace in the sheet-name segment of parentPath."],"exampleFix":"// before\nhandler.Add(\"/Shet1/A1\", \"cell\", null, new() { [\"value\"] = \"x\" });\n// after — ensure the sheet exists first\nEnsureSheet(handler, \"Sheet1\");\nhandler.Add(\"/Sheet1/A1\", \"cell\", null, new() { [\"value\"] = \"x\" });","handlingStrategy":"validation","validationCode":"string sheet = cellPath.TrimStart('/').Split('/', 2)[0];\nif (h.Query(\"/\").All(n => !n.Name.Equals(sheet, StringComparison.OrdinalIgnoreCase)))\n    throw new ArgumentException($\"Sheet '{sheet}' does not exist.\");\nh.Add(cellPath, \"cell\", pos, props);","typeGuard":null,"tryCatchPattern":"try { h.Add(cellPath, \"cell\", pos, props); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Sheet not found\"))\n{ /* create the sheet or correct the name */ }","preventionTips":["Resolve sheet names dynamically rather than hardcoding.","Create sheets before cells in batch replays.","Verify the sheet exists after any rename/delete operation."],"tags":["excel","xlsx","cell","sheet-not-found","path"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}