{"record":{"id":"be960d9475f6da6d","repo":"iOfficeAI/OfficeCLI","slug":"sheet-not-found-groupsheetname-drawing-group-m","errorCode":null,"errorMessage":"Sheet not found: {groupSheetName}. drawing-group must be added under a sheet.","messagePattern":"Sheet not found: (.+?)\\. drawing-group must be added under a sheet\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.cs","lineNumber":1121,"sourceCode":"                    )\n                );\n                chartPart.ChartSpace.Save();\n\n                var chartIdx = drawingsPart.ChartParts.ToList().IndexOf(chartPart);\n                return (relId, $\"/{sheetName}/chart[{chartIdx + 1}]\");\n\n            case \"drawing-group\":\n            {\n                // Verbatim DrawingML group carrier for xlsx dump→batch.\n                // The full hosting anchor is preserved because flattening a\n                // <xdr:grpSp> loses the child coordinate system, z-order,\n                // styles and the fact that the objects are grouped. Only\n                // hyperlink relationships are carried here; dump falls back\n                // to semantic leaf shapes when a group references package\n                // parts such as images/charts.\n                var groupSheetName = parentPartPath.TrimStart('/');\n                var groupWorksheet = FindWorksheet(groupSheetName)\n                    ?? throw new ArgumentException(\n                        $\"Sheet not found: {groupSheetName}. drawing-group must be added under a sheet.\");\n                properties ??= new Dictionary<string, string>();\n                var anchorXml = properties.GetValueOrDefault(\"anchor-xml\")\n                    ?? throw new ArgumentException(\n                        \"'anchor-xml' property is required for drawing-group (verbatim xdr anchor XML)\");\n\n                XDR.TwoCellAnchor groupAnchor;\n                try\n                {\n                    groupAnchor = new XDR.TwoCellAnchor(anchorXml);\n                }\n                catch (Exception ex)\n                {\n                    throw new ArgumentException(\n                        $\"drawing-group anchor XML is not a valid xdr:twoCellAnchor: {ex.Message}\", ex);\n                }\n                if (groupAnchor.GetFirstChild<XDR.GroupShape>() == null)\n                    throw new ArgumentException(","sourceCodeStart":1103,"sourceCodeEnd":1139,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.cs#L1103-L1139","documentation":"Thrown by AddPart when handling a 'drawing-group' part type: the carrier for a verbatim DrawingML group (<xdr:grpSp>) anchor. The parent part path is stripped of a leading '/' and used as a sheet name to locate the hosting worksheet via FindWorksheet. A group anchor must be appended into a sheet's DrawingsPart, so if no worksheet matches the name, the add cannot proceed. FindWorksheet is case-insensitive but otherwise exact.","triggerScenarios":"Calling AddPart(parentPartPath, \"drawing-group\", ...) where parentPartPath (after TrimStart('/')) does not resolve to any worksheet name — e.g. an internal OOXML path like \"/xl/drawings/drawing1.xml\", a renamed/deleted sheet, a sheet[N] index that no longer exists, or an empty string.","commonSituations":"Replaying a dump into a workbook whose target sheet was renamed or removed between dump and batch; passing the package part path instead of the sheet display name; typo or trailing whitespace in the sheet name; referencing a sheet by 1-based index after sheets were reordered.","solutions":["Pass the sheet display name as the parent path (e.g. \"/Sheet1\"), not an internal part path.","List available sheets first and use the exact name (case-insensitive match is accepted).","If replaying a dump, re-run the dump against the current file so sheet names stay in sync.","If the sheet was intentionally removed, drop the drawing-group entry from the batch or target a surviving sheet."],"exampleFix":"// before — internal path, no sheet named 'xl/drawings/drawing1.xml'\nhandler.AddPart(\"/xl/drawings/drawing1.xml\", \"drawing-group\", props);\n// after — sheet display name as parent path\nhandler.AddPart(\"/Sheet1\", \"drawing-group\", props);","handlingStrategy":"validation","validationCode":"var name = parentPartPath.TrimStart('/');\nvar exists = handler.GetWorksheets()\n    .Any(w => w.Name.Equals(name, StringComparison.OrdinalIgnoreCase));\nif (!exists) { /* list sheets, fix path, abort */ }","typeGuard":"static bool SheetResolves(ExcelHandler h, string parentPartPath) =>\n    h.GetWorksheets().Any(w => w.Name.Equals(\n        parentPartPath.TrimStart('/'), StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { handler.AddPart(parentPartPath, \"drawing-group\", props); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Sheet not found\"))\n{ /* reconcile sheet name, then retry with corrected path */ }","preventionTips":["Always pass a sheet display name (e.g. /Sheet1), never an internal part path.","Refresh the dump before replay so sheet names match the live workbook.","Validate the parent path against GetWorksheets() in a pre-flight check."],"tags":["excel","openxml","add-part","drawing-group","sheet-lookup"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}