vercel / vercel/workflow

DurableAgent rejects MCP dynamic tools that have no validate function on inputSchema

Open
#1,576 1 comment 2 reactions 1 assignee View on GitHub

@gr2m is already working on this.

Since Apr 8, 2026.

Dominant language
TypeScript
Stars
2.4k
Forks
365
Avg merge
2d 11h
Merged PRs (30d)
169

Description

Bug

DurableAgent.executeTool() in @workflow/ai@4.1.0-beta.59 incorrectly rejects tool calls for MCP dynamic tools whose inputSchema (created via jsonSchema() from @ai-sdk/provider-utils) has no validate function.

Reproduction

Use @ai-sdk/mcp to create MCP tools (which produces dynamicTool with jsonSchema() wrapper — no validate fn), then pass them to a DurableAgent. When the model calls any of these tools, the agent throws:

Error: Invalid input for tool "toolName": undefined

Root cause

In durable-agent.js L677–693:

const input = await schema.validate?.(JSON.parse(toolCall.input || '{}'));
if (!input?.success) {
    throw new Error(`Invalid input for tool "${toolCall.toolName}": ${input?.error?.message}`);
}
  1. schema.validate is undefined for MCP dynamic tools (the jsonSchema() helper from @ai-sdk/provider-utils does not set a validate function)
  2. schema.validate?.() returns undefined via optional chaining
  3. !undefined?.success!undefinedtrue — enters the error branch
  4. undefined?.error?.messageundefined — produces the ": undefined" suffix

The AI SDK's own safeValidateTypes handles this correctly by short-circuiting:

if (actualSchema.validate == null) {
    return { success: true, value, rawValue: value };
}

Suggested fix

Add a nullish guard before the validation check:

const input = await schema.validate?.(JSON.parse(toolCall.input || '{}'));
if (input !== undefined && !input.success) {
    // validation ran and failed
    throw new Error(...);
}
parsedInput = input?.value ?? JSON.parse(toolCall.input || '{}');

Or, match the AI SDK pattern:

const parsed = JSON.parse(toolCall.input || '{}');
if (typeof schema.validate === 'function') {
    const input = await schema.validate(parsed);
    if (!input.success) {
        throw new Error(`Invalid input for tool "${toolCall.toolName}": ${input.error?.message}`);
    }
    parsedInput = input.value;
} else {
    parsedInput = parsed;
}

Environment

  • @workflow/ai: 4.1.0-beta.59
  • ai: 6.0.142
  • @ai-sdk/mcp: 1.0.30
  • @ai-sdk/provider-utils: 4.0.21
  • @modelcontextprotocol/sdk: 1.29.0

Workaround

Patch a passthrough validate onto MCP tool schemas before passing them to DurableAgent:

if (schema && typeof schema.validate !== "function") {
    schema.validate = (value: unknown) => ({ success: true, value });
}

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.