vercel/ai · error

Unsupported role: ${role}

Error message

Unsupported role: ${role}

What it means

convertToXaiChatMessages maps LanguageModelV4Prompt roles (system/user/assistant/tool) to xAI chat messages. The default branch is an exhaustiveness guard: it fires when a prompt contains a role the xAI chat adapter does not recognize, meaning the SDK's internal prompt and the provider adapter are out of sync (e.g. a newer role added to the spec without xAI support, or a corrupted prompt passed in by custom code).

Source

Thrown at packages/xai/src/convert-to-xai-chat-messages.ts:175

            case 'content':
            case 'json':
            case 'error-json':
              contentValue = JSON.stringify(output.value);
              break;
          }

          messages.push({
            role: 'tool',
            tool_call_id: toolResponse.toolCallId,
            content: contentValue,
          });
        }
        break;
      }

      default: {
        const _exhaustiveCheck: never = role;
        throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
      }
    }
  }

  return { messages, warnings };
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Upgrade @ai-sdk/xai and ai to matching latest versions so prompt roles and adapter support align
  2. Check any custom prompt-building/middleware code for roles the xAI chat model does not support
  3. Remove or convert unsupported roles (e.g. merge tool messages) before sending to xAI

Example fix

// before (custom prompt construction)
const prompt = [{ role: 'developer' as any, content: [{ type: 'text', text: 'hi' }] }];
// after
const prompt = [{ role: 'system', content: [{ type: 'text', text: 'hi' }] }];
Defensive patterns

Strategy: type-guard

Validate before calling

const supported = new Set(['system','user','assistant','tool']);
if (!prompt.every(m => supported.has(m.role))) throw new Error('prompt has roles unsupported by xai chat model');

Type guard

function hasSupportedRoles(prompt: LanguageModelV4Prompt): boolean {
  const ok = new Set(['system', 'user', 'assistant', 'tool'] as const);
  return prompt.every(m => ok.has(m.role as 'system'));
}

Try / catch

try {
  await generateText({ model: xai('grok-4'), prompt });
} catch (e) {
  if ((e as Error).message.startsWith('Unsupported role:')) {
    // rebuild/re-map the prompt before retrying
  }
}

Prevention

When it happens

Trigger: Passing a LanguageModelV4Prompt containing a role outside system/user/assistant/tool to streamText/generateText with an xai(...) chat model — practically only reachable via SDK version mismatch, monkey-patched prompts, or custom pipeline code building prompts manually.

Common situations: Mixing @ai-sdk/provider spec versions (e.g. a prompt built for LanguageModelV2 with roles like 'tool-result' differences) fed to the v4-based xAI provider; custom middleware injecting unsupported role objects.

Related errors


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