vercel/ai · error · UnsupportedFunctionalityError

'system messages are only supported at the beginning of the

Error message

'system messages are only supported at the beginning of the conversation' functionality is not supported.

What it means

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.

Source

Thrown at packages/google/src/convert-to-google-messages.ts:261

      if (v != null) return v as Record<string, unknown>;
    }
    // Cross-namespace fallback (gateway interop): Vertex providers may receive
    // metadata under `google`, and the Google provider may receive metadata
    // under `googleVertex`/`vertex`.
    if (isVertexLike) {
      return part.providerOptions?.google as
        | Record<string, unknown>
        | undefined;
    }
    return (part.providerOptions?.googleVertex ??
      part.providerOptions?.vertex) as Record<string, unknown> | undefined;
  };

  for (const { role, content } of prompt) {
    switch (role) {
      case 'system': {
        if (!systemMessagesAllowed) {
          throw new UnsupportedFunctionalityError({
            functionality:
              'system messages are only supported at the beginning of the conversation',
          });
        }

        systemInstructionParts.push({ text: content });
        break;
      }

      case 'user': {
        systemMessagesAllowed = false;

        const parts: GoogleContentPart[] = [];

        for (const part of content) {
          switch (part.type) {
            case 'text': {
              parts.push({ text: part.text });

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Move all system content into a single system message at position 0 of the prompt.
  2. Convert mid-conversation system messages into user-role messages prefixed with instructions.
  3. Use the provider's `system` option (prompt-level system instruction) instead of system messages inside the array.

Example fix

// before
messages: [{ role: 'user', content: 'hi' }, { role: 'system', content: 'be brief' }]
// after
messages: [{ role: 'system', content: 'be brief' }, { role: 'user', content: 'hi' }]
Defensive patterns

Strategy: validation

Validate before calling

function systemOnlyAtStart(messages) {
  let seenNonSystem = false;
  return messages.every(m => {
    if (m.role === 'system') { if (seenNonSystem) return false; }
    else seenNonSystem = true;
    return true;
  });
}
// validate before calling the Google model

Type guard

function hasOnlyLeadingSystemMessages(prompt) {
  const firstNonSystem = prompt.findIndex(m => m.role !== 'system');
  return !prompt.slice(firstNonSystem + 1).some(m => m.role === 'system');
}

Try / catch

try {
  return await streamText({ model: googleModel, messages });
} catch (e) {
  if (e?.message?.includes('system messages are only supported at the beginning')) {
    const fixed = [...messages.filter(m => m.role === 'system'), ...messages.filter(m => m.role !== 'system')];
    return streamText({ model: googleModel, messages: fixed });
  } throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/e8e2e521b2e890c9. Report an issue: GitHub.