{"record":{"id":"5a51c4665f53f0a1","repo":"conductor-oss/conductor","slug":"failed-to-generate-pdf-from-markdown","errorCode":null,"errorMessage":"Failed to generate PDF from markdown","messagePattern":"Failed to generate PDF from markdown","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/pdf/MarkdownToPdfConverter.java","lineNumber":105,"sourceCode":"                            compact);\n\n            // Step 6: Render AST to PDF\n            PdfDocumentRenderer renderer =\n                    new PdfDocumentRenderer(ctx, imageResolver, request.getImageBaseUrl());\n            renderer.render(markdownAst);\n\n            // Step 7: Close the last content stream\n            if (ctx.getContentStream() != null) {\n                ctx.getContentStream().close();\n            }\n\n            // Step 8: Save to bytes\n            ByteArrayOutputStream out = new ByteArrayOutputStream();\n            document.save(out);\n            return out.toByteArray();\n\n        } catch (IOException e) {\n            throw new RuntimeException(\"Failed to generate PDF from markdown\", e);\n        }\n    }\n\n    private Document parseMarkdown(String markdown) {\n        MutableDataSet options = new MutableDataSet();\n        options.set(\n                Parser.EXTENSIONS,\n                List.of(\n                        TablesExtension.create(),\n                        StrikethroughExtension.create(),\n                        TaskListExtension.create(),\n                        FootnoteExtension.create(),\n                        AutolinkExtension.create(),\n                        DefinitionExtension.create()));\n\n        Parser parser = Parser.builder(options).build();\n        return parser.parse(markdown);\n    }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/pdf/MarkdownToPdfConverter.java#L87-L123","documentation":"Thrown by MarkdownToPdfConverter.convert when PDFBox (PDDocument / PDPageContentStream) raises an IOException during rendering or document.save(). The converter catches IOException specifically and wraps it as a RuntimeException with a generic message, preserving the cause. Indicates a failure in the PDF generation pipeline: font issues, content-stream errors, image encoding failures, or output-stream problems.","triggerScenarios":"An image referenced in the markdown cannot be resolved/encoded by the imageResolver; a font required for the text is missing; content-stream operations fail (e.g. page is full, matrix error); document.save() fails (disk full, encoding error); malformed markdown AST triggers a rendering path PDFBox rejects.","commonSituations":"Broken/unsupported image format in markdown; missing font on the server; very large document exhausting memory; a content-stream state bug during multi-page rendering; transient I/O error writing the ByteArrayOutputStream (rare).","solutions":["Inspect e.getCause() (the IOException) — its message names the exact PDFBox failure.","If the cause is image-related, validate/resolve images before convert() and remove or convert unsupported formats.","If font-related, ensure required fonts are available or embed them.","Reproduce with a minimal markdown sample to isolate which element (image, table, code block) triggers it."],"exampleFix":"// before\nbyte[] pdf = converter.convert(req);\n// after\ntry {\n    byte[] pdf = converter.convert(req);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof java.io.IOException io) {\n        log.error(\"PDFBox failure rendering markdown: {}\", io.getMessage(), io);\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate images/fonts referenced in the markdown before convert.\n// Ensure imageResolver can resolve every ![](url) and required fonts are present.","typeGuard":null,"tryCatchPattern":"try {\n    byte[] pdf = converter.convert(request);\n} catch (RuntimeException e) {\n    Throwable root = e.getCause();\n    if (root instanceof java.io.IOException io) {\n        log.error(\"PDFBox IOException: {}\", io.getMessage(), io);\n    }\n    throw e;\n}","preventionTips":["Inspect the wrapped IOException cause for the precise PDFBox failure.","Resolve/validate images and ensure fonts are available before converting.","Reproduce with a minimal markdown sample to isolate the failing element."],"tags":["pdf","pdfbox","io","rendering","error-handling"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}