FlowiseAI/Flowise · error · Error

System message should be the first one

Error message

System message should be the first one

What it means

Google's Generative AI API only accepts a system message at position 0 of the conversation; it does not support interleaved or trailing system messages. This guard runs inside the message-reduction loop in FlowiseChatGoogleGenerativeAI and throws the moment author === 'system' && index !== 0. It is a hard API contract violation against Gemini/Google models, not a transient failure.

Source

Thrown at packages/components/nodes/chatmodels/ChatGoogleGenerativeAI/FlowiseChatGoogleGenerativeAI.ts:417

}

export function convertBaseMessagesToContent(
    messages: BaseMessage[],
    isMultimodalModel: boolean,
    convertSystemMessageToHumanContent: boolean = false,
    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 {

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Reorder the messages array so the single SystemMessage (if any) is at index 0 before calling the Google model.
  2. Remove or merge any non-leading SystemMessage into the first user/human message as text.
  3. If memory is re-adding system messages, configure the memory node to prepend (not append) or filter SystemMessage types from history.
  4. If you need persistent instructions per turn, convert them to HumanMessage/AIMessage content rather than SystemMessage.

Example fix

// before
messages = [humanMsg, systemMsg, humanMsg2]
await model.invoke(messages) // throws [80]

// after
const sys = messages.filter(m => getMessageAuthor(m) === 'system')
const rest = messages.filter(m => getMessageAuthor(m) !== 'system')
messages = (sys.length ? [sys[0]] : []).concat(rest)
await model.invoke(messages)
Defensive patterns

Strategy: validation

Validate before calling

function validateMessagesForGoogle(messages) {
  for (let i = 0; i < messages.length; i++) {
    const author = getMessageAuthor(messages[i])
    if (author === 'system' && i !== 0) {
      throw new Error(`System message at index ${i} must be moved to index 0 for Google models`)
    }
  }
}
validateMessagesForGoogle(messages)
await model.invoke(messages)

Type guard

import { BaseMessage, SystemMessage } from '@langchain/core/messages'
function isSystemMessage(m: unknown): m is SystemMessage {
  return BaseMessage.isInstance(m) && m.getType() === 'system'
}

Try / catch

try {
  await model.invoke(sanitizeForGoogle(messages))
} catch (e) {
  if (e.message === 'System message should be the first one') {
    // reorder and retry once
    const sys = messages.filter(m => getMessageAuthor(m) === 'system')
    const rest = messages.filter(m => getMessageAuthor(m) !== 'system')
    await model.invoke([...sys.slice(0,1), ...rest])
  } else throw e
}

Prevention

When it happens

Trigger: A chat history containing a SystemMessage at any index other than 0 — e.g. a memory module re-injecting a system prompt, a follow-up chain that prepends instructions before a user turn but after another message, or concatenated prompt templates that emit SystemMessage after a HumanMessage.

Common situations: Chatflows with a 'System Prompt' node placed downstream of memory or another message; custom agents that insert system-style instructions between turns; migrations from OpenAI (which tolerates mid-conversation system messages) to Gemini; prompt templating that always wraps messages in a leading SystemMessage regardless of position.

Related errors


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