Skip to content

[BUG] tool-output-available TypeValidationError with Anthropic SDK — toUIMessageStream() path not covered by PR #1202 #1290

@Phantomn

Description

@Phantomn

Describe the bug

PR #1202 fixed providerMetadata forwarding in convertFullStreamChunkToUIMessageStream (guardrail pipeline path), but there is a second, uncovered path that still causes TypeValidationError: unrecognized_keys ["providerMetadata"] on tool-output-available chunks when using @ai-sdk/anthropic.

The error is thrown in the console.voltagent.dev browser client when it parses the SSE stream via parseJsonEventStream({ schema: uiMessageChunkSchema }) — the browser bundle's schema does not include providerMetadata on tool-output-available.

Root cause chain

@ai-sdk/anthropic@3.0.78 (line 3832)
  → tool-call.providerMetadata = { anthropic: { caller: { type: "direct" } } }

ai@6.0.182 (line 3056)
  → tool-result.providerMetadata = (copied from tool-call)

ai@6.0.182 toUIMessageStream() (line 8121)
  → SSE: { type: "tool-output-available", ..., providerMetadata: { anthropic: { caller: ... } } }

console.voltagent.dev browser bundle
  → parseJsonEventStream + old uiMessageChunkSchema
  → TypeValidationError: unrecognized_keys ["providerMetadata"]

The key difference from PR #1202 (Google Vertex thinking models): Anthropic's caller metadata is injected by @ai-sdk/anthropic on every tool call, not just thinking models. The propagation happens entirely within the AI SDK's toUIMessageStream() method — VoltAgent's convertFullStreamChunkToUIMessageStream is never involved in this path.

Path analysis

Path 1 (fixed by PR #1202): guardrail pipeline
result.fullStreamconvertFullStreamChunkToUIMessageStreamguardrailPipeline.createUIStream() → SSE

Path 2 (still broken): no guardrail / AI SDK direct
result.toUIMessageStream()createUIMessageStream({ writer.merge(...) }) → SSE
↑ This is getGuardrailAwareUIStream when !guardrailPipeline (line ~32047 in 2.7.4)

Steps to reproduce

  1. Use @ai-sdk/anthropic as the model provider (any version that sends caller in API response)
  2. Call an agent with any tool
  3. Observe TypeValidationError on tool-output-available in the VoltAgent console

Error

Type validation failed: Value: {"type":"tool-output-available","toolCallId":"...","output":{...},"providerMetadata":{"anthropic":{"caller":{"type":"direct"}}}}.
Error message: [{"code":"invalid_union","errors":[[...],["code":"unrecognized_keys","keys":["providerMetadata"]],...]}]

Packages

  • @voltagent/core: 2.7.4 (also reproduced on 2.7.1, 2.7.2, 2.7.3)
  • @ai-sdk/anthropic: 3.0.78
  • ai: 6.0.182

Expected behavior

tool-output-available chunks with providerMetadata should not cause a validation error. Either:

  1. The console client schema should be updated to accept providerMetadata on tool-output-available (correct fix), or
  2. The server should strip providerMetadata from tool-output-available before sending SSE (workaround)

Workaround

Add a strip transform in toUIMessageStreamSanitized (VoltAgent core):

const stripProviderMetadataFromUIStream = (stream: ReadableStream) =>
  stream.pipeThrough(new TransformStream({
    transform(chunk, controller) {
      if (chunk?.type === "tool-output-available" && "providerMetadata" in chunk) {
        const { providerMetadata: _pm, ...rest } = chunk;
        controller.enqueue(rest);
      } else {
        controller.enqueue(chunk);
      }
    }
  }));

const toUIMessageStreamSanitized = (streamOptions) => {
  const resolvedStreamOptions = applyResponseMessageId(streamOptions);
  const baseStream = agent.subAgentManager.hasSubAgents()
    ? createMergedUIStream(resolvedStreamOptions)
    : getGuardrailAwareUIStream(resolvedStreamOptions);
  return attachFeedbackMetadata(stripProviderMetadataFromUIStream(baseStream));
};

This issue is related to #1195 and PR #1202 but affects Anthropic users independently of thinking models.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions