[Spreadsheets] artifact-tool 2.8.59 turns no-fill cells with empty color nodes solid black
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.901.51231 (build 8109); bundled runtime 26.905.11957
What subscription do you have?
Not specified; reproducible directly in the local bundled runtime
What platform is your computer?
macOS 26.4.1, arm64; Node.js 24.19.0; @oai/artifact-tool 2.8.59
What issue are you seeing?
Importing an XLSX whose default fill is patternType="none" with empty and children produces an opaque black worksheet preview, making black text invisible. An unedited import/export round trip also changes the fill to patternType="solid".
A synthetic 2-column, 3-row workbook reproduces this without business data. The control with no color children renders normally. PNG black pixels have RGBA (0,0,0,255), so this is not transparent-image viewer compositing.
Computed style reports pattern.patternType:1 for the control and pattern.patternType:2 for the trigger. Exported trigger fill becomes <x:patternFill patternType="solid" />.
What steps can reproduce the bug?
- Create a small workbook using the bundled package:
import { Workbook, SpreadsheetFile } from '@oai/artifact-tool';
const wb = Workbook.create();
const s = wb.worksheets.add('Sheet1');
s.getRange('A1:B3').values = [['Text','Example'],['Arial 123','Sample A'],['More text','Sample B']];
s.getRange('A1:B3').format.columnWidth = 24;
s.getRange('A1:B3').format.font = {name:'Arial',size:11,color:'#000000'};
wb.recalculate();
await (await SpreadsheetFile.exportXlsx(wb)).save('base.xlsx');
- Copy base.xlsx to trigger.xlsx, replacing only the first patternFill in xl/styles.xml within the ZIP. Preserve the namespace prefix (x: in my test).
Control:
<x:patternFill patternType="none" />
Trigger:
<x:patternFill patternType="none"><x:fgColor/><x:bgColor/></x:patternFill>
- Import, render and export without editing any cells:
import fs from 'node:fs/promises';
import { FileBlob, SpreadsheetFile } from '@oai/artifact-tool';
const wb = await SpreadsheetFile.importXlsx(await FileBlob.load('trigger.xlsx'));
console.log((await wb.inspect({kind:'computedStyle',sheetId:'Sheet1',range:'B2',maxChars:2000})).ndjson);
const png = await wb.render({sheetName:'Sheet1',range:'A1:B3',scale:1.5});
await fs.writeFile('preview.png',new Uint8Array(await png.arrayBuffer()));
wb.recalculate();
await (await SpreadsheetFile.exportXlsx(wb)).save('roundtrip.xlsx');
- Compare preview.png and xl/styles.xml in roundtrip.xlsx for both variants. Control stays white/no-fill; trigger becomes black/solid.
What is the expected behavior?
No-fill semantics should take precedence over irrelevant color children: patternType="none" should render with the normal worksheet background and remain none after import/export.
Additional information
Test matrix:
| Input patternFill | Preview | Round-trip XML |
|---|---|---|
| none, no color children | White/readable | none |
| none, empty fgColor/bgColor | Opaque black | solid, no explicit color |
| none, both colors rgb=00000000 | Opaque black | solid, fgColor rgb=FF000000 |
| none, foreground red/background white | White, but semantics changed | solid, fgColor rgb=FFFFFFFF |
| Empty patternFill, no attributes/children | White/readable | none |
Workaround: remove fgColor/bgColor only from fills explicitly marked patternType=none before importing. This restores rendering and round-trip no-fill semantics.
Setting range.format.fill=null after import did not resolve the affected workbook. An explicit white fill restores text inside that range but changes the intended formatting and leaves affected cells outside the range black. Arial and SimSun text are readable once the fill is normalized. Native Excel displays no-fill normally in a structurally valid workbook.
This appears to be an import/style-conversion defect, not solely a PNG rendering issue. Package internals were not inspected, so the exact implementation cause is not asserted. Please route to the bundled spreadsheet/artifact-tool runtime maintainers. No private workbook, business data, or local user paths are included in this report.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the provided Node.js reproduction with @oai/artifact-tool 2.8.59, comparing the control and trigger workbooks. Inspect xl/styles.xml before and after the import/export round trip and compare the rendered preview. Done means patternType="none" with empty color nodes renders as no fill and remains none in the exported workbook.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100