conductor-oss/conductor · error · RuntimeException
Failed to generate PDF from markdown
Error message
Failed to generate PDF from markdown
What it means
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.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/pdf/MarkdownToPdfConverter.java:105
compact);
// Step 6: Render AST to PDF
PdfDocumentRenderer renderer =
new PdfDocumentRenderer(ctx, imageResolver, request.getImageBaseUrl());
renderer.render(markdownAst);
// Step 7: Close the last content stream
if (ctx.getContentStream() != null) {
ctx.getContentStream().close();
}
// Step 8: Save to bytes
ByteArrayOutputStream out = new ByteArrayOutputStream();
document.save(out);
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Failed to generate PDF from markdown", e);
}
}
private Document parseMarkdown(String markdown) {
MutableDataSet options = new MutableDataSet();
options.set(
Parser.EXTENSIONS,
List.of(
TablesExtension.create(),
StrikethroughExtension.create(),
TaskListExtension.create(),
FootnoteExtension.create(),
AutolinkExtension.create(),
DefinitionExtension.create()));
Parser parser = Parser.builder(options).build();
return parser.parse(markdown);
}View on GitHub (pinned to cf7c3e4a8a)
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.
Example fix
// before
byte[] pdf = converter.convert(req);
// after
try {
byte[] pdf = converter.convert(req);
} catch (RuntimeException e) {
if (e.getCause() instanceof java.io.IOException io) {
log.error("PDFBox failure rendering markdown: {}", io.getMessage(), io);
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate images/fonts referenced in the markdown before convert. // Ensure imageResolver can resolve every  and required fonts are present.
Try / catch
try {
byte[] pdf = converter.convert(request);
} catch (RuntimeException e) {
Throwable root = e.getCause();
if (root instanceof java.io.IOException io) {
log.error("PDFBox IOException: {}", io.getMessage(), io);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Failed to read skill file: {e.getMessage()}
- Failed to read skill package: {e.getMessage()}
- Failed to read InputStream for upload
- Failed to list MCP tools from {serverUrl}: {message}
- Failed to call MCP tool '{toolName}' on {serverUrl}: {messag
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/5a51c4665f53f0a1.
Report an issue: GitHub.