What happened?
A zero-edit round-trip (open → save → close) through the SuperDoc CLI silently corrupts the DOCX by:
- Injecting 197 explicit
w:rFonts elements into heading runs that previously had no run-level formatting (inheriting font from their w:pStyle definition)
- Dropping ~61KB from
word/document.xml (741,386 → 680,141 bytes)
- Modifying
word/styles.xml (62,027 → 65,997 bytes) and word/numbering.xml (24,639 → 23,011 bytes)
This causes headings to render with different fonts when opened in Microsoft Word, because the injected partial w:rFonts (e.g., w:ascii="Arial" w:hAnsi="Arial" without w:eastAsia or w:cs) breaks the style inheritance chain and causes Word to fall back to the theme font (Aptos Display) for some rendering paths.
Before (correct):
<!-- Paragraph style=Ttulo1, which defines Arial Bold 16pt -->
<w:r>
<w:t>Article One — Heading Text</w:t>
<!-- No rPr → inherits Arial from Ttulo1 style -->
</w:r>
After open→save (corrupted):
<w:r>
<w:rPr>
<w:rFonts w:ascii="Arial" w:hAnsi="Arial"/>
<!-- Partial rFonts injected — breaks theme font inheritance in Word -->
</w:rPr>
<w:t>Article One — Heading Text</w:t>
</w:r>
The same corruption reproduces in the browser editor (exportDocx()) and the headless CLI — confirming it's in the core OOXML serializer, not the React wrapper or browser APIs.
Impact
Documents opened in Word after a SuperDoc round-trip show visibly different heading fonts, colors, and sizing. For legal document workflows (trusts, contracts), this level of formatting corruption is unacceptable.
Reproduction
The affected document uses localized Portuguese-named heading styles (e.g., Ttulo1 for heading 1, Ttulo2 for heading 2) generated by estate planning document software. These styles define explicit w:rFonts at the style level, and heading runs inherit via w:pStyle with no run-level w:rPr.
CLI reproduction (3 commands):
cp input.docx output.docx
superdoc open output.docx
superdoc save
superdoc close
Verification script (Python):
import zipfile, xml.etree.ElementTree as ET
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
for label, path in [('BEFORE', 'input.docx'), ('AFTER', 'output.docx')]:
with zipfile.ZipFile(path) as z:
tree = ET.parse(z.open('word/document.xml'))
root = tree.getroot()
rfonts = sum(
1 for p in root.iter(f'{{{ns["w"]}}}p')
for r in p.findall('.//w:r', ns)
if r.find('.//w:rPr/w:rFonts', ns) is not None
)
doc_size = len(z.read('word/document.xml'))
print(f'{label}: document.xml={doc_size} bytes, w:rFonts in runs={rfonts}')
Expected output:
BEFORE: document.xml=741386 bytes, w:rFonts in runs=130
AFTER: document.xml=680141 bytes, w:rFonts in runs=327
I will attach the sanitized reproduction DOCX file (all text replaced with lorem ipsum, no real content) in a comment below.
rFonts injection breakdown by paragraph style
| Style ID |
Style Name |
Before |
After |
Injected |
Ttulo3 |
heading 3 |
1 |
131 |
+130 |
Ttulo2 |
heading 2 |
0 |
124 |
+124 |
Sumrio1 |
toc 1 |
0 |
30 |
+30 |
Ttulo1 |
heading 1 |
0 |
16 |
+16 |
Ttulo4 |
heading 4 |
0 |
10 |
+10 |
TitleDocument |
Title Document |
0 |
2 |
+2 |
DocumentTitle |
— |
0 |
1 |
+1 |
TitlePage |
— |
0 |
1 |
+1 |
DocumentTOC |
— |
0 |
1 |
+1 |
Document characteristics that trigger the bug
- Styles use localized (Portuguese)
w:styleId names (Ttulo1, Ttulo2, etc.) with English w:name values (heading 1, heading 2)
- Heading styles define fonts via explicit
w:rFonts at the style level: w:ascii="Arial" w:hAnsi="Arial" w:cs="Times New Roman"
- Theme fonts are
majorFont=Aptos Display, minorFont=Aptos
- Heading runs have no
w:rPr — they rely entirely on style inheritance
- Document includes TOC styles (
Sumrio1, Sumrio2), custom styles (TitleDocument, TextHeading2, TextHeading3), and complex numbering definitions
A simpler DOCX with standard English-named styles (Heading 1, Heading 2) does not trigger the rFonts injection — SuperDoc injects w:color instead but not w:rFonts. The localized style names appear to be a factor.
Environment
@superdoc-dev/cli v0.5.1
superdoc v1.24.2 (browser — same result)
@superdoc-dev/react v1.0.0-rc.2 (browser — same result)
- Node.js v22.22.2
- macOS (ARM64)
Related issues
SuperDoc version
@superdoc-dev/cli v0.5.1, superdoc v1.24.2
Browser
Not applicable (reproduced headlessly via CLI)
Additional context
The round-trip also loses ~61KB from document.xml even with zero edits. This suggests the serializer is dropping or restructuring OOXML elements it doesn't fully model internally. The word/theme/theme1.xml is the only part that survives completely unchanged.
The documentation states "Round-trip fidelity: import, edit, export — nothing lost" — this reproduction directly contradicts that claim for documents with localized heading styles.
What happened?
A zero-edit round-trip (
open→save→close) through the SuperDoc CLI silently corrupts the DOCX by:w:rFontselements into heading runs that previously had no run-level formatting (inheriting font from theirw:pStyledefinition)word/document.xml(741,386 → 680,141 bytes)word/styles.xml(62,027 → 65,997 bytes) andword/numbering.xml(24,639 → 23,011 bytes)This causes headings to render with different fonts when opened in Microsoft Word, because the injected partial
w:rFonts(e.g.,w:ascii="Arial" w:hAnsi="Arial"withoutw:eastAsiaorw:cs) breaks the style inheritance chain and causes Word to fall back to the theme font (Aptos Display) for some rendering paths.Before (correct):
After open→save (corrupted):
The same corruption reproduces in the browser editor (
exportDocx()) and the headless CLI — confirming it's in the core OOXML serializer, not the React wrapper or browser APIs.Impact
Documents opened in Word after a SuperDoc round-trip show visibly different heading fonts, colors, and sizing. For legal document workflows (trusts, contracts), this level of formatting corruption is unacceptable.
Reproduction
The affected document uses localized Portuguese-named heading styles (e.g.,
Ttulo1for heading 1,Ttulo2for heading 2) generated by estate planning document software. These styles define explicitw:rFontsat the style level, and heading runs inherit viaw:pStylewith no run-levelw:rPr.CLI reproduction (3 commands):
Verification script (Python):
Expected output:
I will attach the sanitized reproduction DOCX file (all text replaced with lorem ipsum, no real content) in a comment below.
rFonts injection breakdown by paragraph style
Ttulo3Ttulo2Sumrio1Ttulo1Ttulo4TitleDocumentDocumentTitleTitlePageDocumentTOCDocument characteristics that trigger the bug
w:styleIdnames (Ttulo1,Ttulo2, etc.) with Englishw:namevalues (heading 1,heading 2)w:rFontsat the style level:w:ascii="Arial" w:hAnsi="Arial" w:cs="Times New Roman"majorFont=Aptos Display,minorFont=Aptosw:rPr— they rely entirely on style inheritanceSumrio1,Sumrio2), custom styles (TitleDocument,TextHeading2,TextHeading3), and complex numbering definitionsA simpler DOCX with standard English-named styles (
Heading 1,Heading 2) does not trigger the rFonts injection — SuperDoc injectsw:colorinstead but notw:rFonts. The localized style names appear to be a factor.Environment
@superdoc-dev/cliv0.5.1superdocv1.24.2 (browser — same result)@superdoc-dev/reactv1.0.0-rc.2 (browser — same result)Related issues
SuperDoc version
@superdoc-dev/cli v0.5.1, superdoc v1.24.2
Browser
Not applicable (reproduced headlessly via CLI)
Additional context
The round-trip also loses ~61KB from
document.xmleven with zero edits. This suggests the serializer is dropping or restructuring OOXML elements it doesn't fully model internally. Theword/theme/theme1.xmlis the only part that survives completely unchanged.The documentation states "Round-trip fidelity: import, edit, export — nothing lost" — this reproduction directly contradicts that claim for documents with localized heading styles.