Issue 325 Form PDF Download Failed - edmozley/freeitsm GitHub Wiki
GitHub #325, reported by pappas81 ยท Forms ยท broken in 4.11.0, fixed in 5.2.0 (#2879)
Open a form's submissions (Forms โ a form โ Submissions), open a submission, press Download PDF: a red toast, The PDF could not be created, and no file. Nothing in the server's logs - the PDF is made in the browser, so the server never knew. The same went for ticking rows and choosing One PDF or Separate PDFs.
The report came from a Docker install, but Docker had nothing to do with it - it failed the same way on every install from 4.11.0 to 5.1.0. Exporting the same records from a collection page worked all along.
In 4.11.0 every PDF export moved from jsPDF to one shared writer over PDFKit (assets/js/pdf-writer.js, GH #254), so Polish and every other language FreeITSM ships would print. jsPDF made a document straight away; PDFKit has to be loaded first, and so do the fonts the text needs - a Hindi answer fetches the Devanagari font. So making a document became asynchronous:
// assets/js/form-pdf.js - newDoc() hands back a Promise of a document, not a document
function newDoc(text) {
return window.FitsmPdf.create({ unit: 'mm', format: 'a4', orientation: 'portrait' }, text);
}The shared Forms code (form-pdf.js) was moved over properly: its exportOne(), exportBundle() and exportSeparate() all await the document. forms/collection.php calls those, which is why collections kept working.
forms/submissions.php did not. It had its own copy of the export steps, written in the jsPDF days, and in 4.11.0 only its <script> tags were changed - not the code underneath:
// forms/submissions.php, 4.11.0 to 5.1.0
const newPdfDoc = () => FormPdf.newDoc(); // a Promise...
...
const doc = newPdfDoc(); // ...never awaited
drawSubmission(doc, sub, idx, await loadBrandLogo()); // draws on a Promise -> TypeErrorThe first drawing call on the Promise threw, the catch showed the toast, and the real error went only to the browser console.
tests/pdf-writer.php (20 checks) tests the writer, through its own probe page. It never opened a Forms page. The writer was right; one of its callers was not.
Every caller of FitsmPdf.create() and FormPdf.newDoc() was swept: Knowledge, Report Packs, Morning Checks, data tables, asset labels, Change Management, Network and Process Mapper and the org chart all await it. forms/submissions.php was the only one that did not.
The page no longer has its own copy. Its three exports go through the shared functions that collection.php already used, so the two pages cannot drift apart again:
// forms/submissions.php, 5.2.0
const pdfItem = (sub, idx) => ({ form: formData, sub: sub, num: filteredSubmissions.length - idx });
// Download PDF on one submission
const it = pdfItem(sub, idx);
await FormPdf.exportOne(it.form, it.sub, it.num, LOGO_URL);
// ticked rows: One PDF, or Separate PDFs
const items = rows.map(r => pdfItem(r.sub, r.idx));
if (mode === 'bundle') await FormPdf.exportBundle(items, formData.title, LOGO_URL);
else await FormPdf.exportSeparate(items, LOGO_URL);The documents are the same as before - same layout, same file names (Form - Name - 31 Oct 2026.pdf, Form - 6 submissions - date.pdf), same "#3" numbering - because drawSubmission() was always the shared one. The page-local helpers it no longer needs (newPdfDoc, drawSubmission, stampFooters, loadBrandLogo, the file-name wrappers) are gone, and a TRAP: comment says why.
| File | Change |
|---|---|
forms/submissions.php |
Download PDF, One PDF and Separate PDFs through FormPdf.exportOne / exportBundle / exportSeparate; the page's own copy of the steps removed |
Headless Chrome on a throwaway install, on the real submissions page of a form with 6 submissions, with the browser's download replaced by a recorder: Download PDF handed over New starter request - Karen Hall - 31 Oct 2026.pdf; One PDF over the 6 ticked rows handed over New starter request - 6 submissions - 13 Nov 2026.pdf; Separate PDFs handed over one file per row. No toast, nothing in the console.
The control is the code itself: on 5.1.0 newPdfDoc() returns a Promise and the next line calls a drawing method on it - which cannot work in any browser.
- On 4.11.0 to 5.1.0? Download PDF on a form's submissions page fails. Until you upgrade, a collection that holds the form exports the same records correctly.
- On 5.2.0 it works. Nothing to set up.
- PDF writer - Developer Guide - why making a document is asynchronous
- Forms
- Bugs resolved