{"record":{"id":"1b6f1c94dcc24a6d","repo":"FlowiseAI/Flowise","slug":"system-message-should-be-the-first-one","errorCode":null,"errorMessage":"System message should be the first one","messagePattern":"System message should be the first one","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/chatmodels/ChatGoogleGenerativeAI/FlowiseChatGoogleGenerativeAI.ts","lineNumber":417,"sourceCode":"}\n\nexport function convertBaseMessagesToContent(\n    messages: BaseMessage[],\n    isMultimodalModel: boolean,\n    convertSystemMessageToHumanContent: boolean = false,\n    model?: string\n) {\n    return messages.reduce<{\n        content: Content[]\n        mergeWithPreviousContent: boolean\n    }>(\n        (acc, message, index) => {\n            if (!BaseMessage.isInstance(message)) {\n                throw new Error('Unsupported message input')\n            }\n            const author = getMessageAuthor(message)\n            if (author === 'system' && index !== 0) {\n                throw new Error('System message should be the first one')\n            }\n            const role = convertAuthorToRole(author)\n\n            const prevContent = acc.content[acc.content.length]\n            if (!acc.mergeWithPreviousContent && prevContent && prevContent.role === role) {\n                throw new Error('Google Generative AI requires alternate messages between authors')\n            }\n\n            const parts = convertMessageContentToParts(message, isMultimodalModel, messages.slice(0, index), model)\n\n            if (acc.mergeWithPreviousContent) {\n                const prevContent = acc.content[acc.content.length - 1]\n                if (!prevContent) {\n                    throw new Error('There was a problem parsing your system message. Please try a prompt without one.')\n                }\n                prevContent.parts.push(...parts)\n\n                return {","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/chatmodels/ChatGoogleGenerativeAI/FlowiseChatGoogleGenerativeAI.ts#L399-L435","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reorder the messages array so the single SystemMessage (if any) is at index 0 before calling the Google model.","Remove or merge any non-leading SystemMessage into the first user/human message as text.","If memory is re-adding system messages, configure the memory node to prepend (not append) or filter SystemMessage types from history.","If you need persistent instructions per turn, convert them to HumanMessage/AIMessage content rather than SystemMessage."],"exampleFix":"// before\nmessages = [humanMsg, systemMsg, humanMsg2]\nawait model.invoke(messages) // throws [80]\n\n// after\nconst sys = messages.filter(m => getMessageAuthor(m) === 'system')\nconst rest = messages.filter(m => getMessageAuthor(m) !== 'system')\nmessages = (sys.length ? [sys[0]] : []).concat(rest)\nawait model.invoke(messages)","handlingStrategy":"validation","validationCode":"function validateMessagesForGoogle(messages) {\n  for (let i = 0; i < messages.length; i++) {\n    const author = getMessageAuthor(messages[i])\n    if (author === 'system' && i !== 0) {\n      throw new Error(`System message at index ${i} must be moved to index 0 for Google models`)\n    }\n  }\n}\nvalidateMessagesForGoogle(messages)\nawait model.invoke(messages)","typeGuard":"import { BaseMessage, SystemMessage } from '@langchain/core/messages'\nfunction isSystemMessage(m: unknown): m is SystemMessage {\n  return BaseMessage.isInstance(m) && m.getType() === 'system'\n}","tryCatchPattern":"try {\n  await model.invoke(sanitizeForGoogle(messages))\n} catch (e) {\n  if (e.message === 'System message should be the first one') {\n    // reorder and retry once\n    const sys = messages.filter(m => getMessageAuthor(m) === 'system')\n    const rest = messages.filter(m => getMessageAuthor(m) !== 'system')\n    await model.invoke([...sys.slice(0,1), ...rest])\n  } else throw e\n}","preventionTips":["Always build the messages array with the system prompt at index 0 when targeting Google models.","Unit-test message ordering before invoking Gemini-family models.","Filter SystemMessage out of chat-memory output before re-injection.","When migrating from OpenAI, run a one-time alternation/order lint over saved chatflows."],"tags":["google-generative-ai","message-ordering","validation","gemini","system-prompt"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}