{"record":{"id":"e8e2e521b2e890c9","repo":"vercel/ai","slug":"system-messages-are-only-supported-at-the-beginni","errorCode":null,"errorMessage":"'system messages are only supported at the beginning of the conversation' functionality is not supported.","messagePattern":"'system messages are only supported at the beginning of the conversation' functionality is not supported\\.","errorType":"exception","errorClass":"UnsupportedFunctionalityError","httpStatus":null,"severity":"error","filePath":"packages/google/src/convert-to-google-messages.ts","lineNumber":261,"sourceCode":"      if (v != null) return v as Record<string, unknown>;\n    }\n    // Cross-namespace fallback (gateway interop): Vertex providers may receive\n    // metadata under `google`, and the Google provider may receive metadata\n    // under `googleVertex`/`vertex`.\n    if (isVertexLike) {\n      return part.providerOptions?.google as\n        | Record<string, unknown>\n        | undefined;\n    }\n    return (part.providerOptions?.googleVertex ??\n      part.providerOptions?.vertex) as Record<string, unknown> | undefined;\n  };\n\n  for (const { role, content } of prompt) {\n    switch (role) {\n      case 'system': {\n        if (!systemMessagesAllowed) {\n          throw new UnsupportedFunctionalityError({\n            functionality:\n              'system messages are only supported at the beginning of the conversation',\n          });\n        }\n\n        systemInstructionParts.push({ text: content });\n        break;\n      }\n\n      case 'user': {\n        systemMessagesAllowed = false;\n\n        const parts: GoogleContentPart[] = [];\n\n        for (const part of content) {\n          switch (part.type) {\n            case 'text': {\n              parts.push({ text: part.text });","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/google/src/convert-to-google-messages.ts#L243-L279","documentation":"Google's Gemini API only accepts a system instruction as a single, leading `systemInstruction` field, not as system-role messages interleaved in the conversation. When the converter encounters a 'system' message after the conversation has started (systemMessagesAllowed is false), it throws UnsupportedFunctionalityError because there is no valid Google representation for a mid-conversation system message.","triggerScenarios":"Building a prompt array where a `{ role: 'system' }` message appears after any assistant/user message, then calling generateText/streamText with a Google (Gemini or Vertex) model. Also triggered by tool-result-then-system patterns in multi-step agent loops.","commonSituations":"Agent loops that inject a system reminder between turns; porting OpenAI chat histories that contain mid-conversation system messages; frameworks that append per-turn system prompts.","solutions":["Move all system content into a single system message at position 0 of the prompt.","Convert mid-conversation system messages into user-role messages prefixed with instructions.","Use the provider's `system` option (prompt-level system instruction) instead of system messages inside the array."],"exampleFix":"// before\nmessages: [{ role: 'user', content: 'hi' }, { role: 'system', content: 'be brief' }]\n// after\nmessages: [{ role: 'system', content: 'be brief' }, { role: 'user', content: 'hi' }]","handlingStrategy":"validation","validationCode":"function systemOnlyAtStart(messages) {\n  let seenNonSystem = false;\n  return messages.every(m => {\n    if (m.role === 'system') { if (seenNonSystem) return false; }\n    else seenNonSystem = true;\n    return true;\n  });\n}\n// validate before calling the Google model","typeGuard":"function hasOnlyLeadingSystemMessages(prompt) {\n  const firstNonSystem = prompt.findIndex(m => m.role !== 'system');\n  return !prompt.slice(firstNonSystem + 1).some(m => m.role === 'system');\n}","tryCatchPattern":"try {\n  return await streamText({ model: googleModel, messages });\n} catch (e) {\n  if (e?.message?.includes('system messages are only supported at the beginning')) {\n    const fixed = [...messages.filter(m => m.role === 'system'), ...messages.filter(m => m.role !== 'system')];\n    return streamText({ model: googleModel, messages: fixed });\n  } throw e;\n}","preventionTips":["Keep a single system message at index 0 in prompt arrays for Google.","In agent loops, inject per-turn instructions as user messages, not system messages.","Add a message-shape lint/test for prompts sent to Gemini/Vertex."],"tags":["google","gemini","messages","system-prompt"],"backgroundTag":"system-message-position-unsupported","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}