Situation
I have been experiencing inconsistent output from my Gemini node (regardless of the model) - currently on models/gemini-2.5-flash. n8n self-hosted last version.
The issue resides in the fact that Gemini will runs my query twice: one test “John Doe” (supposingly hardcoded my Google - TBC, not able to find any reference for this), and one my expected response.
Therefore, the output of my node contains 2 runs/payloads (not 2 items in the same payload).
Subsequently, it doesn’t seem that we can prevent this, or use any trick to select the given payload.
And it doesn’t seem that I can control the order of the payloads.
Tests performed, but unsuccessful
- Use a List node to select only the last one since the List node will always use the 1st payload from the previous node (Gemini). And since I can’t control the output payload, it may use my John Doe payload.
- Use the Merge node, but similar to the List node, it merges the content of the same payload.
- Use Code node, but here again, it is using the last payload with using such a code:
// Gemini returns multiple items/runs. Keep only the last one.
const lastItem = items[items.length - 1].json;
// The model's actual structured output is usually in `text` or `content`.
let parsed;
try {
parsed = JSON.parse(lastItem.text || lastItem.content || JSON.stringify(lastItem));
} catch (e) {
throw new Error("Could not parse Gemini output: " + e.message);
}
return [{ json: parsed }];
Temporary fix
I managed to fix this, temporarily I assume, by restarting my n8n docker container.
For miraculous reason, the payload, still produces 2 outputs, but my response is not falling into the 1st run, therefore, my workflow can continue.
After some research, I have a javascript to use in a Code node to be tested in the future. I put it here for reference if anyone would be interested to test it.
/**
* Function node directly after Gemini.
* Drops runs that don't contain valid JSON (e.g., the "John Doe" preview),
* and forwards only the parsed JSON when present.
*/
function extractText(payload) {
// Try common fields the Gemini/LangChain nodes use
if (typeof payload === 'string') return payload;
if (typeof payload?.text === 'string') return payload.text;
if (typeof payload?.content === 'string') return payload.content;
if (Array.isArray(payload?.content) && typeof payload.content[0]?.text === 'string') return payload.content[0].text;
if (typeof payload?.response === 'string') return payload.response;
if (typeof payload?.output === 'string') return payload.output;
if (typeof payload?.output_text === 'string') return payload.output_text;
if (payload?.choices?.[0]?.message?.content) return payload.choices[0].message.content;
if (payload?.generations?.[0]?.text) return payload.generations[0].text;
return undefined;
}
// In this run, we expect a single item from Gemini
const payload = items[0]?.json ?? {};
const text = extractText(payload);
if (!text || typeof text !== 'string') {
// Nothing usable in this run → drop it
return [];
}
// Accept only valid JSON
try {
const parsed = JSON.parse(text.trim());
return [{ json: parsed }];
} catch (e) {
// Not valid JSON → drop first run (e.g. "John Doe")
return [];
}
If anyone came up with this issue, please provide a response with your testing, as I’m afraid this issue will resurface for me, and I’d like to get to the bottom of it. Thanks

