Repository navigation
fix(mailings): header and footer fields stay unresolved after merge #430
Description
Summary
A recipient field inserted in an attached header stays as «Name» during Preview Results and after Finish & Merge. The same field in the body resolves correctly. The erroneous header result persists in the saved DOCX and after reopening. A footer inserted through the analogous public command has the same failure.
Steps to reproduce
Use the CLI runtime described below. Run the following in a disposable directory with wordcraft-cli on PATH. This one-recipient fixture was executed locally; it needs no recipient file or existing document.
wordcraft-cli run --template blank --print \
--cmd 'mailings.recipients={"rows":[{"Name":"Alpha"}]}' \
--cmd 'insert.header={"text":"Recipient: "}' \
--cmd caret.docEnd \
--cmd 'mailings.insertField={"field":"Name"}' \
--cmd insert.closeHeader \
--cmd 'text.insert={"text":"Body: "}' \
--cmd 'mailings.insertField={"field":"Name"}' \
--cmd 'mailings.preview={"value":true}' \
--cmd document.inspect \
--cmd 'mailings.preview={"value":false}' \
--cmd document.inspect \
--cmd 'mailings.finish={"from":1,"to":1}' \
--cmd document.inspect \
--save merged.docx
wordcraft-cli inspect merged.docxCompare the body and part texts in each inspection. Repeat the same commands in a fresh session with insert.footer in place of insert.header to reproduce the footer variant. Both variants were run, saved, and reopened successfully.
To inspect the stored field independently, run this comparison after the header fixture:
python3 - <<'PY'
import zipfile
import xml.etree.ElementTree as ET
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
with zipfile.ZipFile('merged.docx') as z:
for name in ('word/document.xml', 'word/header1.xml'):
root = ET.fromstring(z.read(name))
text = ''.join(e.text or '' for e in root.findall('.//w:t', ns))
fields = [e.text for e in root.findall('.//w:instrText', ns)]
print(name, repr(text), fields)
PYExpected behavior
Preview Results should show Recipient: Alpha in the attached header and Body: Alpha in the body. Turning preview off should restore the merge-field placeholders. Finishing the selected recipient should produce Recipient: Alpha and Body: Alpha in the saved document, with the recipient fields resolved to text. The same contract applies to the accepted footer field.
Actual behavior
Every fixture command exited successfully. With preview enabled, inspection showed Body: Alpha and the attached header as Recipient: «Name». With preview disabled, the body correctly returned to Body: «Name»; the header did not change. Finish returned {"records":1} and resolved the body to Body: Alpha, while the attached header still read Recipient: «Name».
The saved DOCX contained body text Body: Alpha with no body field instructions. Its header contained Recipient: «Name» and the instruction MERGEFIELD Name. A fresh CLI inspection of the saved file showed the same incorrect header text. The footer variant gave the corresponding unresolved footer result in memory, in its stored XML, and after reopening.
Evidence
Source locators below refer to the current recheck source. Original execution identity is retained under Runtime or environment.
- Expected source:
README.md:119documents mail merge fields, preview and finish to a document. The public command declarations incrates/engine/src/cmd/insert.rs:45andcrates/engine/src/cmd/mailings.rs:60support creating header/footer parts and inserting a merge field at the active selection, without a body-only restriction. The preview contract atcrates/engine/src/cmd/mailings.rs:377specifies recipient values during preview, and the finish contract at line 420 specifies that fields become plain text. - Failure source: The executed inline fixture's inspections, independently read
word/document.xmlandword/header1.xml, and fresh CLI inspection of the saved DOCX all show the unresolved attached header alongside the resolved body. The footer variant reproduces the same result. Source checks atcrates/engine/src/cmd/mailings.rs:378and line 421 confirm that preview evaluates body paragraphs and finish merges body blocks while retaining the document parts. - Evidence provenance: observed
- Local verification: reproduced
- Reproduction completeness: complete
The primary violation evidence is execution through the public CLI and inspection of the stored output. Source inspection separately supports reachability and scope. Both header and footer cases were executed, saved, independently inspected as DOCX XML, and reopened.
The fixture uses a fresh unprotected document, a known field name, one recipient, and the same field-insertion command in both stories. Its body control demonstrates that recipient loading and ordinary merge evaluation work. The accepted selection remains in the attached header or footer until Close Header and Footer returns it to the body.
The current recheck independently searched all 170 listed issue bodies and read the relevant live comments and fixing patches. No matching open or closed report was found for this failure; routing remains a separate new bug report.
Restoration check
Run the header fixture and its footer variant. With preview enabled, both the body and attached part must show Alpha. With preview disabled, both must show the Name placeholder, which prevents replacing the template field permanently just to satisfy preview. After finish, independently inspect and reopen the saved DOCX: the body and attached part must retain Alpha and no unresolved Name merge field. Keep the attached part and the Recipient: prefix; deleting the part or moving its content into the body does not restore the contract.
Runtime or environment
- Original verification source baseline:
4615cef8784b6fc23a6cd356070802ccba21098f. The supplied read-only checkout was directly verified at this revision with a clean working tree. - Original runtime: the supplied native macOS build, reporting
wordcraft-cli 0.4.0; independently measured binary SHA-2560424c3df03f1e565a5c862f5cef3158342d3726a18d1a40181e088b4df4f0f6b. Its source association comes from the supplied build provenance. - All runtime checks used synthetic content and a 60-second timeout per invocation. GUI behavior, external Word rendering, first/even header variants, and automated multi-recipient header results were not tested.
- Current recheck source:
e4b7d155f15a7784197ba34eeea0b54490d70eb2, directly confirmed as clean checkout HEAD. Current supplied native runtime reportswordcraft-cli 0.5.0on macOS; measured executable SHA-256:6292c6e5b24074eed6193529e3003d0d9a987e13db803ad99cb14e4b0f201651. Source association follows the supplied build provenance; this reviewer did not rebuild it. - Current verification: Every executable reproduction in this report was rerun, followed by the meaningful comparison and workaround controls. The attached header and footer remain unresolved in preview, finish, stored XML and reopened output. The body resolves to Alpha, and manual replacement works for the single-record fixture. All CLI fixture invocations completed with exit 0; no GUI execution is claimed.
Additional context
For the single-record case, replacing the header field with the known recipient text before finishing is a verified workaround. After inserting the body field, insert.header={"text":"Recipient: Alpha"} followed by insert.closeHeader and the same finish command produced correct body and header text in the saved and reopened DOCX. This requires manual recipient substitution and does not establish an automated multi-recipient workaround.
Triage assessment
- Impact level: P2
- Assessment status: supported
- Impact basis: Accepted header/footer merge fields remain unresolved in generated output, including the saved document. The demonstrated defect affects a bounded document-part combination; the same body fields work, and no crash or source-document loss was observed.
- Workaround status: available
- Workaround basis: Manual replacement with the recipient's text was demonstrated to preserve the requested header and correct body output for the single-record case. It requires extra editing; automated multi-recipient output was not evaluated.
Activity
vangel76 commentedon Oct 11, 2026
I'll take this together with #427–#430 (mail merge rules bundle). Fix + regression test, PR follows.
Mail merge: SKIPIF, NEXT, IF in preview, header/footer fields (#427, #…