JSON Stringify can't send data to PDF

I’m building a workflow that sends AI agent data to be generated as a pdf file using the ‘PDF Generator API’ node.

I’ve used this command in the node’s ‘data’ field on two previous workflows with the exact same function, and it worked just fine:

{{ JSON.stringify({ post_event_report: $json.output }) }}

But here, it’s generating a blank PDF. I’ve already included the variable in the PDF Generator Template as I’d done for the previous workflows, so I have no idea why it’s suddenly throwing a blank PDF.

Any ideas?

{
“nodes”: [
{
“parameters”: {},
“type”: “n8n-nodes-base.manualTrigger”,
“typeVersion”: 1,
“position”: [
0,
0
],
“id”: “27e200f4-843d-4d50-b42c-0b8a26f7291b”,
“name”: “When clicking ‘Execute workflow’”
},
{
“parameters”: {
“documentId”: {
“__rl”: true,
“value”: “1DSaJKyI1eCp6WZJ8X1aAa6jg7fvOOS5vJFKUmar7quA”,
“mode”: “list”,
“cachedResultName”: “Post Event Reporting”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1DSaJKyI1eCp6WZJ8X1aAa6jg7fvOOS5vJFKUmar7quA/edit?usp=drivesdk
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1DSaJKyI1eCp6WZJ8X1aAa6jg7fvOOS5vJFKUmar7quA/edit#gid=0
},
“options”: {}
},
“type”: “n8n-nodes-base.googleSheets”,
“typeVersion”: 4.7,
“position”: [
224,
0
],
“id”: “3b86eb78-0869-40c3-9bcf-1ad77f80cf74”,
“name”: “Get row(s) in sheet”,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “wV1Zw6McyxYXrk8t”,
“name”: “Google Sheets account”
}
}
},
{
“parameters”: {
“promptType”: “define”,
“text”: “= Get {{ $json.Feedback }} for {{ $json[“Event Name”] }} {{ $json.Date }} {{ $json.Location }} {{ $json[‘No. of Guests’] }}”,
“options”: {
“systemMessage”: "=You are a Post Event Reporting specialist working with a Small Catering Business with over 30 years of experience in the industry. Your role is to analyze the spreadsheet and generate areas of improvement based on the {{ $json.Feedback }} given. Compile all of the data into a comprehensive post-event report "
}
},
“type”: “@n8n/n8n-nodes-langchain.agent”,
“typeVersion”: 3.1,
“position”: [
448,
0
],
“id”: “1cebd084-c6fa-4477-b507-96bffc2a3733”,
“name”: “AI Agent”
},
{
“parameters”: {
“templateId”: {
“__rl”: true,
“value”: “1655316”,
“mode”: “list”,
“cachedResultName”: “Post-Event Report (ID: 1655316)”
},
“data”: “={{ JSON.stringify({ post_event_report: $json.output }) }}”,
“documentOutput”: “viewer”,
“additionalFields”: {
“outputName”: “=Post event report for {{ $(‘Get row(s) in sheet’).item.json[“Event Name”] }} on {{ $(‘Get row(s) in sheet’).item.json.Date }}”,
“testing”: false
}
},
“type”: “@pdfgeneratorapi/n8n-nodes-pdf-generator-api.pdfGeneratorApi”,
“typeVersion”: 1,
“position”: [
800,
0
],
“id”: “4304c3b8-5210-4b2d-8d6d-49eac03b03a6”,
“name”: “Generate a PDF document”,
“alwaysOutputData”: true,
“credentials”: {
“pdfGeneratorApi”: {
“id”: “XUfVEGWx0Q45fr5L”,
“name”: “PDF Generator account”
}
}
},
{
“parameters”: {
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.lmChatGoogleGemini”,
“typeVersion”: 1.1,
“position”: [
320,
208
],
“id”: “630d55ef-1a19-4f5a-bad5-a14c85c8fb4d”,
“name”: “Google Gemini Chat Model”,
“credentials”: {
“googlePalmApi”: {
“id”: “r5K1AFY1c2dmiqsE”,
“name”: “Google Gemini(PaLM) Api account”
}
}
}
],
“connections”: {
“When clicking ‘Execute workflow’”: {
“main”: [
[
{
“node”: “Get row(s) in sheet”,
“type”: “main”,
“index”: 0
}
]
]
},
“Get row(s) in sheet”: {
“main”: [
[
{
“node”: “AI Agent”,
“type”: “main”,
“index”: 0
}
]
]
},
“AI Agent”: {
“main”: [
[
{
“node”: “Generate a PDF document”,
“type”: “main”,
“index”: 0
}
]
]
},
“Google Gemini Chat Model”: {
“ai_languageModel”: [
[
{
“node”: “AI Agent”,
“type”: “ai_languageModel”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “845031bfdb8f607d8c7ae907fb5de28c6fb4d0a8d0cd06c1a605d7c42f4018a9”
}
}

Change this: ={{ JSON.stringify({ post_event_report: $json.output }) }}

To this: = { "post_event_report": $json.output }

Here is the workflow

1 Like

Since this exact pattern worked on two other workflows, the bug is almost certainly in what $json.output actually contains here, not the JSON.stringify approach itself. Two things stand out from your JSON:

  1. alwaysOutputData: true on the PDF node means it’ll happily return a result even when its input is empty/malformed — which is exactly why you’re getting a blank PDF instead of an error. Temporarily remove that setting so a bad input actually surfaces as a failure you can inspect.
  2. Drop a Set node (or just click on the PDF node’s input pin) right before “Generate a PDF document” and check what $json.output actually is at that point. With a LangChain Agent node backed by Gemini specifically, I’ve seen cases where the response comes back nested differently than expected (e.g. under a different key, or as an array) depending on the model/version — so “the same expression that worked before” can silently resolve to undefined this time, and JSON.stringify({ post_event_report: undefined }) produces {} essentially, hence a blank/templated-but-empty PDF.
  3. Also worth checking independently of the data: does the PDF Generator Template (ID 1655316) actually have a merge variable named exactly post_event_report? A rename or a new template ID with a differently-named field would produce the same “blank PDF, no error” symptom even with perfectly good data flowing in.

Isolating whether it’s (2) or (3) is one test: hardcode the data field to {{ JSON.stringify({ post_event_report: “test content” }) }} and run it. If that renders in the PDF, the problem is upstream (Agent output shape). If it’s still blank, the problem is the template/field mapping.

Hi @Tim_Barrett ,

A blank PDF from PDF Generator API usually happens for two specific reasons: Double Stringification or an undefined AI output.

Here is how to fix it:

1. Remove JSON.stringify() (Avoid Double Escaping)

In n8n expression mode (={{ … }}), using JSON.stringify() can cause double-stringification because the community node already serializes objects before sending them to the API. When double-escaped, the PDF Generator API receives an invalid string instead of a valid data object, causing all template fields to render blank.

Try changing the data field in your PDF Generator node from:

={{ JSON.stringify({ post_event_report: $json.output }) }}

To a direct JavaScript object:

={{ { post_event_report: $json.output } }}

2. Check if $json.output is undefined

If the AI Agent output property is missing or named differently, JSON.stringify({ post_event_report: undefined }) evaluates to {} (an empty JSON object). When PDF Generator API receives {} with no matching keys, it renders a blank PDF.

  • Click on your AI Agent node execution output and make sure the key is strictly named output.
  • If Gemini generates multiline markdown text with line breaks (\n), you can safely sanitize/trim it using:
={{ { post_event_report: ($json.output || "").trim() } }}

Quick Test

Try changing the data parameter to a hardcoded string object first to see if your PDF template renders:

={{ { post_event_report: "Test report content here..." } }}

If the test text appears on the PDF, then switching to ={{ { post_event_report: $json.output } }} will solve your issue!

Let me know if this resolves the blank PDF!

Thanks!