Spreadsheet importer returns shared-string index for an empty XLSX shared string
What issue are you seeing?
SpreadsheetFile.importXlsx in the Codex Spreadsheets runtime resolves an XLSX shared-string cell incorrectly when the referenced shared string is empty.
For this valid OOXML:
<!-- xl/worksheets/sheet1.xml -->
<c r="A2" t="s"><v>1</v></c>
<c r="B2" t="s"><v>0</v></c>
<!-- xl/sharedStrings.xml -->
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
count="2" uniqueCount="2">
<si><t>visible</t></si>
<si><t/></si>
</sst>
A2 references shared-string index 1, whose resolved content is an empty string. Codex instead returns the raw index text "1". B2 correctly resolves index 0 to "visible".
This can silently turn blank spreadsheet cells into valid-looking numeric strings. Downstream data transformations can therefore write incorrect values without any parse error.
What steps can reproduce the bug?
Environment:
- Codex App:
26.803.61601(build6396) - Workspace dependencies bundle:
26.805.11740 @oai/artifact-tool:2.8.39- Platform:
Darwin 25.5.0 arm64 arm
- Decode the sanitized workbook included below.
- Import it with the bundled runtime:
import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
const workbook = await SpreadsheetFile.importXlsx(
await FileBlob.load("codex-empty-shared-string-repro.xlsx"),
);
const result = await workbook.inspect({
kind: "table",
sheetId: "Repro",
range: "A1:B2",
include: "values,formulas",
});
console.log(result.ndjson);
- Observe the imported values:
[["empty_shared_string","control"],["1","visible"]]
- Open the same workbook in WPS/Excel-compatible software, or export it with LibreOffice Calc:
empty_shared_string,control
,visible
The independent reader correctly leaves A2 blank.
What is the expected behavior?
A2 should resolve to an empty string (or the importer's documented blank-cell representation), never to the shared-string table index.
Expected values:
[["empty_shared_string","control"],["","visible"]]
Additional information
- The workbook is fully synthetic and contains no user, repository, company, or business data.
- The XLSX ZIP package passes integrity validation and contains only eight standard OOXML entries.
- There are no formulas or external links.
- A structurally identical real-world workbook used a different shared-string index and showed the same failure mode.
- The behavior is consistent with a falsy empty-string resolution falling back to the raw index. This is an inference from the observed boundary, not a source-code-confirmed root cause.
<details>
<summary>Sanitized minimal XLSX (base64, 3.6 KB)</summary>
SHA-256: aa567082dafc74bd1f2c4ab1d124a9917101a66c4777b572c8645a075e287524
Save the block as repro.b64, then decode it:
python3 -c 'import base64,pathlib; pathlib.Path("codex-empty-shared-string-repro.xlsx").write_bytes(base64.b64decode(pathlib.Path("repro.b64").read_text()))'
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
LQwAAAAA
</details>