FlowiseAI/Flowise · error · Error
Google Generative AI requires alternate messages between…
Error message
Google Generative AI requires alternate messages between authors
What it means
Google Generative AI requires strictly alternating author roles (user/model) in its Content[] payload. This guard fires when the current message's converted role equals the previous content's role AND the reducer is not in a merge-with-previous state. Consecutive same-role messages violate Gemini's conversation contract.
Solutions
- Ensure the messages array strictly alternates roles (human, ai, human, ai, ...) before invoking the Google model.
- If consecutive same-role messages are intentional, enable system-merge / content-merging so they collapse into one Content entry.
- Insert a synthetic assistant message (or remove the duplicate) to restore alternation.
- Inspect memory node settings — set a return-by that pairs user/assistant turns (e.g. return both halves of each exchange).
Example fix
// before
messages = [human1, human2, ai1] // two humans in a row -> throws [81]
// after
function enforceAlternation(msgs) {
const out = []
let lastRole = null
for (const m of msgs) {
const role = getMessageAuthor(m)
if (role === lastRole && role !== 'system') {
// merge text into previous same-role message instead of appending
out[out.length - 1].content += '\n\n' + m.content
continue
}
out.push(m)
lastRole = role
}
return out
}
await model.invoke(enforceAlternation(messages)) Defensive patterns
Strategy: validation
Validate before calling
function assertAlternateAuthors(messages) {
let last = null
for (const m of messages) {
const role = convertAuthorToRole(getMessageAuthor(m))
if (last === role && role !== 'system') {
throw new Error(`Consecutive ${role} messages will be rejected by Google`)
}
last = role
}
}
assertAlternateAuthors(messages)
await model.invoke(messages) Type guard
function isConsecutiveSameRole(messages: BaseMessage[]): boolean {
let last = ''
for (const m of messages) {
const r = convertAuthorToRole(getMessageAuthor(m))
if (r === last && r !== 'system') return true
last = r
}
return false
} Try / catch
try {
await model.invoke(messages)
} catch (e) {
if (e.message.includes('alternate messages')) {
await model.invoke(mergeConsecutiveSameRole(messages))
} else throw e
} Prevention
- Pair every user turn with an assistant turn in memory buffers.
- Validate alternation with a lint helper before each invoke.
- Avoid concatenating two user inputs without an assistant bridge.
- When tool-calling, always interleave tool-result messages between AI tool-call messages.
When it happens
Trigger: Two HumanMessages back-to-back, two AIMessages back-to-back, or a function/tool message that maps to 'user' immediately following a 'user' message — without mergeWithPreviousContent being set to absorb the duplicate role. Also triggered by chat memory that appends repeated user turns without an assistant reply in between.
Common situations: Memory buffers that store unpaired user messages (user sent multiple inputs before a reply); tool-calling flows where consecutive AI tool-call messages are not separated by tool-result messages; merged chatflows combining two user inputs without an assistant bridge; OpenAI->Gemini migration since OpenAI is lenient about repeated roles.
Related errors
- System message should be the first one
- There was a problem parsing your system message. Please try…
- Google requires a tool name for each tool call response…
- Invalid media content
- Please provide image as base64 encoded data URL
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/7206eb9fbf6b2d1d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/components/nodes/chatmodels/ChatGoogleGenerativeAI/FlowiseChatGoogleGenerativeAI.ts:423
model?: string
) {
return messages.reduce<{
content: Content[]
mergeWithPreviousContent: boolean
}>(
(acc, message, index) => {
if (!BaseMessage.isInstance(message)) {
throw new Error('Unsupported message input')
}
const author = getMessageAuthor(message)
if (author === 'system' && index !== 0) {
throw new Error('System message should be the first one')
}
const role = convertAuthorToRole(author)
const prevContent = acc.content[acc.content.length]
if (!acc.mergeWithPreviousContent && prevContent && prevContent.role === role) {
throw new Error('Google Generative AI requires alternate messages between authors')
}
const parts = convertMessageContentToParts(message, isMultimodalModel, messages.slice(0, index), model)
if (acc.mergeWithPreviousContent) {
const prevContent = acc.content[acc.content.length - 1]
if (!prevContent) {
throw new Error('There was a problem parsing your system message. Please try a prompt without one.')
}
prevContent.parts.push(...parts)
return {
mergeWithPreviousContent: false,
content: acc.content
}
}
let actualRole = role
if (actualRole === 'function' || (actualRole === 'system' && !convertSystemMessageToHumanContent)) {View on GitHub (pinned to abe4a8601a)