{"record":{"id":"8ee8a513fe66f327","repo":"iOfficeAI/OfficeCLI","slug":"sheet-not-found-spksheetname","errorCode":null,"errorMessage":"Sheet not found: {spkSheetName}","messagePattern":"Sheet not found: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs","lineNumber":963,"sourceCode":"            if (shpWorksheet.DrawingsPart != null) shpWorksheet.DeletePart(shpWorksheet.DrawingsPart);\n            SaveWorksheet(shpWorksheet);\n            throw;\n        }\n    }\n\n    private string AddSlicer(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)\n    {\n        var index = position?.Index;\n        return AddSlicer(parentPath, properties);\n    }\n\n    private string AddSparkline(string parentPath, string type, InsertPosition? position, Dictionary<string, string> properties)\n    {\n        var index = position?.Index;\n        var spkSegments = parentPath.TrimStart('/').Split('/', 2);\n        var spkSheetName = spkSegments[0];\n        var spkWorksheet = FindWorksheet(spkSheetName)\n            ?? throw new ArgumentException($\"Sheet not found: {spkSheetName}\");\n\n        // CONSISTENCY(canonical-key): 'location'/'dataRange' are canonical;\n        // 'cell'/'range'/'data' retained as legacy aliases.\n        // R12a: also accept the host cell from the parent path tail\n        // (e.g. `add /Sheet1/F1 sparkline --prop dataRange=A1:E1`), mirroring\n        // how cell/cf Add derive their target from the path. Explicit\n        // location=/cell= still wins.\n        var spkPathTail = spkSegments.Length > 1\n            && Regex.IsMatch(spkSegments[1], @\"^[A-Z]+\\d+$\", RegexOptions.IgnoreCase)\n            ? spkSegments[1].ToUpperInvariant() : null;\n        var spkCell = properties.GetValueOrDefault(\"location\")\n            ?? properties.GetValueOrDefault(\"cell\")\n            ?? spkPathTail\n            ?? throw new ArgumentException(\"Sparkline requires 'location' (or 'cell') property (e.g. F1)\");\n        var spkRange = properties.GetValueOrDefault(\"dataRange\")\n            ?? properties.GetValueOrDefault(\"datarange\")\n            ?? properties.GetValueOrDefault(\"range\")\n            ?? properties.GetValueOrDefault(\"data\")","sourceCodeStart":945,"sourceCodeEnd":981,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/Handlers/Excel/ExcelHandler.Add.Drawings.cs#L945-L981","documentation":"Thrown by AddSparkline when the first segment of the parent path does not match any worksheet — the same FindWorksheet null-coalescing pattern as error 540. No sparkline XML is constructed before the lookup; this is a precondition check on the host sheet. The path tail (an optional F1-style cell) is parsed only after the sheet is resolved.","triggerScenarios":"Calling `add /WrongSheet sparkline --prop location=F1 --prop dataRange=A1:E1` where `WrongSheet` is absent, renamed, or misspelled. Also when the path is just `/` or empty so the leading segment is blank.","commonSituations":"Sheet renamed in the workbook but the script still references the old name; wrong file opened; path built by string concatenation with an empty sheet variable.","solutions":["Verify the sheet name against the workbook's actual sheets (FindWorksheet is case-insensitive).","Use a path whose first segment is an existing sheet, e.g. `/Sheet1/F1 sparkline` or `/Sheet1 sparkline` with location=."],"exampleFix":"// before\nadd ./book.xlsx /Dashbord sparkline --prop location=F1 --prop dataRange=A1:E1\n// after\nadd ./book.xlsx /Sheet1 sparkline --prop location=F1 --prop dataRange=A1:E1","handlingStrategy":"validation","validationCode":"// Same sheet-existence check as error 540.\nif (!SheetExists(wbp, sheetName))\n    throw new InvalidOperationException($\"Sheet '{sheetName}' not found\");","typeGuard":"static bool SheetExists(WorkbookPart wbp, string sheetName)\n    => wbp.Workbook.Sheets.Elements<Sheet>()\n        .Any(s => s.Name.Value.Equals(sheetName, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { handler.AddSparkline(...); }\ncatch (ArgumentException ex) when (ex.Message.StartsWith(\"Sheet not found\"))\n{ /* list sheets, do not retry with the same name */ }","preventionTips":["Resolve the host sheet dynamically before building the sparkline path.","Centralize sheet-name validation so drawing and sparkline paths share one guard."],"tags":["excel","sheet-not-found","sparkline","input-validation","ooxml"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}