I’v set up a simple form using Form fillout. Everything works perfect except the photo URLs in live production. They appear in the email as none but will appear fine in test mode.
What is the error message (if any)?
Please share your workflow
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
@sbsmooth77 your gmail body pulls from $(‘Webhook’).item.json, and .item relies on paired-item linking that gets dropped across the agent node between the webhook and gmail. so live runs resolve .item empty and the || {} fallback blanks the photo urls, while test rides on pinned data and looks fine. is there an agent or code node between your webhook and the gmail node?
yeah thats the thing, it wasnt about where the photo urls live, $(‘Webhook’).item just cant trace a paired item back through the openai node so it returns empty on live runs. swap .item.json for .first().json in that gmail expression, so JSON.stringify($(‘Webhook’).first().json || {}, null, 2). .first() grabs the webhook output directly instead of chasing the broken paired link, so live will match what you see in test.
So it worked when I ran it live directly from Form Fillout but when I tried running from Go High Level I got the same thing. Any idea why GHL would change it?
makes sense, GHL doesnt send the same payload fillout does, it wraps the submission in its own structure so the photo urls end up at a different path (or different field names) than the value[0].url you had. run one live submission through GHL, open the webhook node output, and find where the file urls actually sit in that json, then point the expression there. if GHL isnt passing the urls through at all, thats the GHL webhook config rather than n8n.
Easiest way to find it @sbsmooth77 trigger one real GHL submission, then check the Executions tab → open that run → look at the Webhook node’s output JSON. Search for .jpg or http to see exactly where the file URL is sitting.
GHL usually nests file uploads under body.customData rather than top-level like Fillout does, so your expression will probably end up something like: