vercel/ai · error · UnsupportedFunctionalityError
The ${model.provider} model "${model.modelId}" does not supp
Error message
The ${model.provider} model "${model.modelId}" does not support batch processing. What it means
The ACP harness fingerprints the active host tool catalog (SHA-256 of the JSON-serialized HarnessV1ToolSpec array) and persists it with the turn. During a lossy rerun (a resumed turn whose full protocol state no longer exists), assertRecoveryToolCatalog compares the persisted fingerprint against the currently configured tools. A mismatch means the rerun would execute against a different tool surface than the original turn, so the harness refuses to proceed rather than replaying with wrong tools.
Source
Thrown at packages/ai/src/batch/batch.ts:224
await stream.pipeTo(transform.writable, {
signal: operationAbortSignal,
});
} catch (error) {
await transform.writable.abort(wrapGatewayError(error)).catch(() => {});
}
})();
return asAsyncIterableStream(transform.readable);
}
function resolveBatchLanguageModel(
modelArg: StartTextBatchOptions['model'],
): BatchLanguageModelV4 {
const model = resolveLanguageModel(modelArg);
if (!isBatchLanguageModel(model)) {
throw new UnsupportedFunctionalityError({
functionality: 'batch processing',
message: `The ${model.provider} model "${model.modelId}" does not support batch processing.`,
});
}
return model;
}
function isBatchLanguageModel(
model: LanguageModelV4,
): model is BatchLanguageModelV4 {
const candidate = model as Partial<BatchLanguageModelV4>;
return (
typeof candidate.experimental_doStartBatch === 'function' &&
typeof candidate.experimental_doGetBatchStatus === 'function' &&
typeof candidate.experimental_doGetBatchResults === 'function'
);
}View on GitHub (pinned to 69428b1f8b)
Solutions
- Restore the exact `tools` array (names, descriptions, parameter schemas, order) that was active when the original turn ran.
- If the tool change is intentional, start a new session/turn instead of rerunning the old one.
- Diff the persisted tool catalog from your lifecycle/turn state against the current HarnessV1ToolSpec[] to identify what changed.
- Pin tool definitions (including MCP server versions) so they are stable across deploys for the lifetime of a session.
Example fix
// before
classifierAgent({ tools: [readFileTool, writeFileTool, grepTool] }) // original turn
// rerun after removing grepTool
agent({ tools: [readFileTool, writeFileTool] }) // throws
// after
agent({ tools: [readFileTool, writeFileTool, grepTool] }) // identical catalog Defensive patterns
Strategy: validation
Validate before calling
import { createHash } from 'node:crypto';
const fingerprint = (tools: unknown) =>
createHash('sha256').update(JSON.stringify(tools)).digest('hex');
// before rerunning, compare against the fingerprint persisted with the turn
if (fingerprint(currentTools) !== persistedToolCatalogFingerprint) {
throw new Error('Tool catalog changed since the original turn; start a new session.');
} Try / catch
try {
await agent.rerunTurn({ turnId });
} catch (error) {
if (error instanceof Error && error.message.includes('same active host tool catalog')) {
// tool catalog drifted: recreate the session with the current catalog
session = await createSession({ tools: currentTools });
} else {
throw error;
}
} Prevention
- Treat the tools array as immutable for the lifetime of a session; version it alongside session state.
- Pin MCP server versions and tool library versions in lockfile/config.
- When tools must change, deliberately create a new session instead of rerunning old turns.
When it happens
Trigger: Resuming/rerunning a previous ACP turn after the `tools` array passed to the harness (or the resolved builtin + MCP tool catalog) changed between the original turn and the rerun; adding, removing, renaming, or reordering host tools; changing tool parameter schemas; switching mcpServers so the effective catalog differs.
Common situations: Deploying a new app version that added or removed a tool while a session was in-flight; toggling MCP servers via env-driven config; a tool library upgrade that changed a tool's name or parameters; reordering tools and assuming order is irrelevant.
Related errors
- ${harnessId} recovered this turn through disk replay only an
- The ACP implementation did not load the active harness-owned
- Invalid argument for parameter requests: requests must not b
- Invalid argument for parameter requests: request IDs must no
- Invalid argument for parameter requests: request IDs must be
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/dcffbef76685c0df.
Report an issue: GitHub.