vercel/ai · error · UnsupportedFunctionalityError

'tool choice type: ${type}' functionality not supported.

Error message

'tool choice type: ${type}' functionality not supported.

What it means

prepareResponsesTools switches on the toolChoice type (auto/none/required/tool). The default branch is an exhaustiveness guard that throws UnsupportedFunctionalityError for any tool-choice type the xAI Responses adapter does not implement — typically reached when the SDK type system is bypassed with a cast or a newer tool-choice type exists that xAI has not mapped.

Source

Thrown at packages/xai/src/responses/xai-responses-prepare-tools.ts:208

      if (selectedTool.type === 'provider') {
        // xAI API does not support forcing specific server-side tools via toolChoice
        // Only function tools can be forced with {"type": "function", "function": {"name": "..."}}
        toolWarnings.push({
          type: 'unsupported',
          feature: `toolChoice for server-side tool "${selectedTool.name}"`,
        });
        return { tools: xaiTools, toolChoice: undefined, toolWarnings };
      }

      return {
        tools: xaiTools,
        toolChoice: { type: 'function', name: selectedTool.name },
        toolWarnings,
      };
    }
    default: {
      const _exhaustiveCheck: never = type;
      throw new UnsupportedFunctionalityError({
        functionality: `tool choice type: ${_exhaustiveCheck}`,
      });
    }
  }
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Use only auto | none | required | { type: 'tool', toolName } for xAI responses models
  2. Replace legacy values like 'any' with 'required'
  3. Upgrade @ai-sdk/xai to the latest version so new tool-choice types are mapped

Example fix

// before
toolChoice: { type: 'any' } as any
// after
toolChoice: { type: 'required' }
Defensive patterns

Strategy: validation

Validate before calling

const allowed = ['auto','none','required','tool'];
if (toolChoice && !allowed.includes(toolChoice.type)) {
  throw new Error(`toolChoice type ${toolChoice.type} not supported by xai`);
}

Type guard

function isXaiToolChoice(tc: unknown): boolean {
  const t = (tc as any)?.type;
  return tc == null || ['auto','none','required','tool'].includes(t);
}

Try / catch

try {
  await generateText({ model, prompt, toolChoice: tc as any });
} catch (e) {
  if ((e as any).name === 'AI_UnsupportedFunctionalityError' && (e as Error).message.includes('tool choice type')) {
    // fall back to toolChoice: 'auto'
  }
}

Prevention

When it happens

Trigger: Passing toolChoice: { type: <unrecognized> } (e.g. a custom/extended value or an old spec value like 'any'/'message') with a cast to the responses-model toolChoice, causing the never check to fail at runtime.

Common situations: Migrating code from other providers where toolChoice values differ (e.g. { type: 'any' } from older SDK versions); hand-constructed provider calls; SDK version skew between spec types and provider package.

Related errors


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