iOfficeAI/OfficeCLI · error · ArgumentException
Target sheet has no data
Error message
Target sheet has no data
What it means
Thrown when the resolved target worksheet (for a cross-sheet row move) has no <sheetData> element. Even though the target sheet exists, it carries no data container, so there is nowhere to insert the moved row. This is the target-side equivalent of 'Sheet has no data'.
Source
Thrown at src/officecli/Handlers/Excel/ExcelHandler.Add.cs:289
?? throw new ArgumentException("Sheet has no data");
// Determine the target sheet's SheetData. The result path is built from
// the resolved target SHEET (below), NOT the raw --to: a row/col/cell
// lives directly under a sheet, so a non-sheet --to like /Sheet1/row[2]
// must not leak into the result path (it used to produce a doubled
// /Sheet1/row[2]/row[3]). Only the sheet segment of --to is meaningful.
SheetData targetSheetData;
if (string.IsNullOrEmpty(targetParentPath))
{
targetSheetData = sheetData;
}
else
{
var tgtSegments = targetParentPath.TrimStart('/').Split('/', 2);
var tgtWorksheet = FindWorksheet(tgtSegments[0])
?? throw new ArgumentException($"Target sheet not found: {tgtSegments[0]}");
targetSheetData = GetSheet(tgtWorksheet).GetFirstChild<SheetData>()
?? throw new ArgumentException("Target sheet has no data");
}
// Find and move the row
var rowMatch = Regex.Match(elementRef, @"^row\[(\d+)\]$");
if (rowMatch.Success)
{
var rowIdx = int.Parse(rowMatch.Groups[1].Value);
// Try ordinal lookup first (Nth row element), then fall back to RowIndex
var allRows = sheetData.Elements<Row>().ToList();
var row = (rowIdx >= 1 && rowIdx <= allRows.Count ? allRows[PathIndex.ToArrayIndex(rowIdx)] : null)
?? sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex?.Value == (uint)rowIdx)
?? throw new ArgumentException($"Row {rowIdx} not found");
// Resolve --before / --after anchors to a 0-based document-order
// position in the target sheet. Anchor must be /<TargetSheet>/row[K].
// Resolved BEFORE removing the moved row so the anchor is found by
// its current position.
int? targetIndex = index;View on GitHub (pinned to 1ced45e900)
Solutions
- Populate the target sheet with at least one row before moving into it.
- Choose a target sheet that already contains data.
- If the target is brand new, seed it with a placeholder row then move.
Example fix
// before
h.Move("/Data/row[1]", "/Fresh", null); // Fresh has no <sheetData>
// after
h.Add("/Fresh", "row", null, new()); // seed so SheetData exists
h.Move("/Data/row[1]", "/Fresh", InsertPosition.AtIndex(1)); Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the target sheet already holds data before moving into it.
var tgt = targetParentPath!.TrimStart('/').Split('/', 2)[0];
var node = handler.Get(tgt, depth: 2);
if (!node.Children.Any(c => c.Type == "row"))
throw new InvalidOperationException("Target sheet has no data; seed it first"); Try / catch
try { handler.Move(src, target, pos); }
catch (ArgumentException ex) when (ex.Message == "Target sheet has no data")
{ /* seed the target with a row, then retry the move */ } Prevention
- Seed empty target sheets with a placeholder row before moving into them.
- Prefer data-bearing sheets as move destinations.
- For brand-new sheets, Add a row first to materialize <sheetData>.
When it happens
Trigger: Moving a row into a freshly-created or empty target sheet that was never populated; target sheet whose data was stripped; minimal template sheet used as a destination.
Common situations: Destination created by Add('sheet') but not yet written to; template sheets with only column defaults; exporter that omits <sheetData> on empty sheets.
Related errors
- Target sheet not found: {tgtSegments[0]}
- Sheet has no data
- Row {rowIdx} not found
- Anchor must be a row path like /{targetSheetName}/row[K], go
- Anchor sheet '{aSegs[0]}' must match target sheet '{targetSh
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/c79e6f49686f48f5.
Report an issue: GitHub.