vercel/ai · error · Error

Unsupported role: ${_exhaustiveCheck}

Error message

Unsupported role: ${_exhaustiveCheck}

What it means

convertToAlibabaChatMessages switches over each prompt message role ('system', 'user', 'assistant', 'tool'); the default branch is an exhaustiveness check that should be unreachable. Hitting it means a message with a role the Alibaba converter does not recognize reached the conversion step, and the TypeScript never-narrowing failed at runtime (e.g. due to a cast or an untyped object).

Source

Thrown at packages/alibaba/src/convert-to-alibaba-chat-messages.ts:216

            role: 'tool',
            tool_call_id: toolResponse.toolCallId,
            content: partCacheControl
              ? [
                  {
                    type: 'text',
                    text: contentValue,
                    cache_control: partCacheControl,
                  },
                ]
              : contentValue,
          });
        }
        break;
      }

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

  return messages;
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Inspect the prompt array you pass to generateText/streamText and fix or remove the message with the invalid role
  2. Validate message roles against 'system' | 'user' | 'assistant' | 'tool' before building the prompt
  3. Remove any `as any`/type assertions that bypass Message typing
  4. Update the ai package and @ai-sdk/alibaba to latest versions in case a new core message role was added without provider support

Example fix

// before
const messages = [{ role: 'system_message', content: 'hi' } as any];
await generateText({ model: alibaba('qwen-max'), messages });
// after
const messages: Array<CoreMessage> = [{ role: 'system', content: 'hi' }];
await generateText({ model: alibaba('qwen-max'), messages });
Defensive patterns

Strategy: validation

Validate before calling

const VALID = new Set(['system','user','assistant','tool']);
function assertValidRoles(messages: unknown[]): asserts messages {
  for (const m of messages as { role: string }[]) {
    if (!VALID.has(m.role)) throw new Error(`Invalid message role: ${m.role}`);
  }
}
assertValidRoles(messages);

Type guard

function isCoreMessage(m: unknown): m is CoreMessage {
  return typeof m === 'object' && m !== null &&
    ['system','user','assistant','tool'].includes((m as any).role);
}

Prevention

When it happens

Trigger: Calling generateText/streamText with an alibaba chat model and passing a message whose role is not one of the four supported strings — typically via an `as any`/untyped prompt array, or a plugin/interceptor injecting a custom message object.

Common situations: Constructing prompt arrays programmatically from an API payload with a typo like 'usr' or 'system_message'; older/newer SDK message types leaking into the prompt; JSON-driven message construction without schema validation.

Related errors


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