Skip to content

fix(ai): serialize Date in tool-result json output so Postgres timestamps don't crash multi-tool loops (#2433)#2491

Open
javieraldape wants to merge 1 commit into
garrytan:masterfrom
javieraldape:fix/2433-tool-result-date-iso
Open

fix(ai): serialize Date in tool-result json output so Postgres timestamps don't crash multi-tool loops (#2433)#2491
javieraldape wants to merge 1 commit into
garrytan:masterfrom
javieraldape:fix/2433-tool-result-date-iso

Conversation

@javieraldape

Copy link
Copy Markdown

Summary

Fixes #2433. Any multi-tool rollout or subagent loop that called a brain tool returning Postgres timestamp columns (e.g. brain_list_pages, brain_query) crashed AI SDK v6 validation with AI_InvalidPromptError: The messages do not match the ModelMessage[] schema.

Root cause

node-postgres deserializes timestamp columns into JS Date instances. toModelMessages() (src/core/ai/gateway.ts) emitted the tool result in its json branch as { type: 'json', value: b.output }, passing those Dates through raw. AI SDK v6's jsonValueSchema accepts only null | string | number | boolean | record | array — not Date — so the entire message tree was rejected.

Fix

JSON-roundtrip the value in the json branch so Dates (including nested ones) serialize to ISO strings the validator accepts:

value: JSON.parse(JSON.stringify(b.output ?? null)) as never

Scope kept tight: the error-text branch already stringifies and is untouched; no BigInt handling added (that's a separate concern, #2450).

Test

test/gateway-model-messages.test.ts gains a case feeding a tool-result whose output nests a Date, asserting it serializes to the ISO string. Confirmed it fails on the pre-fix code (receives a raw Date) and passes after. The issue author independently verified the fix on a real workload (subagent rollout success 1/5 → 5/5).

Verification

  • bun run typecheck → clean (EXIT=0)
  • bun test test/gateway-model-messages.test.ts → all pass

Closes #2433.

🤖 Generated with Claude Code

…amps don't crash multi-tool loops (garrytan#2433)

node-postgres returns timestamp columns as JS Date instances. toModelMessages() emitted tool results in the json branch as { type: 'json', value: b.output }, passing those Dates raw; AI SDK v6's jsonValueSchema rejects Date, so any multi-tool/subagent loop that called a brain tool returning timestamps aborted with AI_InvalidPromptError. JSON-roundtrip the value so Dates serialize to ISO strings the validator accepts. Regression test pins the conversion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ModelMessage[] schema rejects Date in tool-result output.value (Postgres timestamps crash multi-tool loops)

1 participant