FlowiseAI/Flowise · error · Error

Google Generative AI requires alternate messages between aut

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.

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)

Solutions

  1. Ensure the messages array strictly alternates roles (human, ai, human, ai, ...) before invoking the Google model.
  2. If consecutive same-role messages are intentional, enable system-merge / content-merging so they collapse into one Content entry.
  3. Insert a synthetic assistant message (or remove the duplicate) to restore alternation.
  4. 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

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


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/7206eb9fbf6b2d1d. Report an issue: GitHub.