different-ai/openwork · error · Error

XLSX workbook contained no sheets.

Error message

XLSX workbook contained no sheets.

What it means

Error thrown when an XLSX attachment contains a workbook.xml but it declares no sheet entries. This happens with edge-case or corrupt workbooks (e.g., all sheets deleted before saving, or malformed output from a third-party generator). The parser cannot extract any tabular data without at least one sheet. Fix by opening the file in a spreadsheet app, ensuring at least one sheet with data exists, and saving/re-uploading it.

Source

Thrown at apps/server/src/opencode-plugins/openwork-office-attachments.ts:637

      ...(displayValue !== undefined ? { displayedValue: displayValue } : {}),
    });
  }
  return { dimension, mergedRanges, cells, omittedCells };
}

function quoted(value: string): string {
  const encoded = JSON.stringify(value.length > 500 ? `${value.slice(0, 500)}…` : value);
  return typeof encoded === "string" ? encoded : "\"\"";
}

function extractXlsxText(bytes: Buffer): string {
  const entries = zipEntryMap(listZipEntries(bytes));
  const workbookXml = readZipTextEntry(bytes, entries, "xl/workbook.xml");
  if (!workbookXml) throw new Error("XLSX workbook.xml was not found.");
  const sharedStrings = parseSharedStrings(readZipTextEntry(bytes, entries, "xl/sharedStrings.xml"));
  const numberFormats = parseXlsxNumberFormats(readZipTextEntry(bytes, entries, "xl/styles.xml"));
  const sheets = parseWorkbookSheets(workbookXml, readZipTextEntry(bytes, entries, "xl/_rels/workbook.xml.rels"));
  if (sheets.length === 0) throw new Error("XLSX workbook contained no sheets.");

  const lines = [
    "xlsx_workbook:",
    `  sheet_count: ${sheets.length}`,
    `  shared_string_count: ${sharedStrings.length}`,
    `  style_count: ${numberFormats.length}`,
    "  sheets:",
  ];
  let remainingCells = MAX_XLSX_CELLS;
  for (const sheet of sheets.slice(0, MAX_XLSX_SHEETS)) {
    lines.push(`  - name: ${quoted(sheet.name)}`);
    lines.push(`    sheet_id: ${quoted(sheet.sheetId)}`);
    if (sheet.relationshipId) lines.push(`    relationship_id: ${quoted(sheet.relationshipId)}`);
    lines.push(`    path: ${quoted(sheet.path)}`);
    const safeSheetPath = sheet.path.startsWith("xl/worksheets/") && sheet.path.endsWith(".xml") ? sheet.path : "";
    const sheetXml = safeSheetPath ? readZipTextEntry(bytes, entries, safeSheetPath) : null;
    if (!sheetXml) {
      lines.push("    error: worksheet XML was not found or was outside xl/worksheets");

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Open the workbook in Excel, confirm it has sheets, and re-save it.
  2. If generated programmatically, fix the generator to emit valid <sheet> entries in workbook.xml.
  3. Check any XML-sanitizing step isn't stripping sheet elements.
  4. Re-export the file from the originating tool.

Example fix

// before: workbook.xml with no sheets
<workbook><bookViews>...</bookViews></workbook>
// after
<workbook><sheets><sheet name="Sheet1" sheetId="1" r:id="rId1"/></sheets></workbook>
Defensive patterns

Strategy: validation

Validate before calling

function workbookHasSheets(workbookXml: string): boolean {
  return /<sheet[\s>]/i.test(workbookXml);
}

Type guard

function hasExtractableSheets(sheets: unknown[]): boolean {
  return Array.isArray(sheets) && sheets.length > 0;
}

Try / catch

try {
  const text = extractXlsxText(bytes);
} catch (err) {
  if (err instanceof Error && err.message.includes("no sheets")) {
    throw new ApiError(400, "invalid_xlsx", "Workbook has no sheets; re-save the file from Excel.");
  }
  throw err;
}

Prevention

When it happens

Trigger: extractOfficeText("xlsx", bytes) on a workbook.xml containing no <sheet> elements (or names the parser could not match) — damaged workbooks, programmatically generated files that omit sheets, or files stripped by sanitizers.

Common situations: Scripts generating xlsx with malformed workbook.xml; sanitizer/redaction pipelines that stripped sheet elements; corrupted files where relationship parsing dropped all sheets.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/7260a1b9968ceaf0. Report an issue: GitHub.