Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Failed server tool call is saved without `error`, so it reloads as complete

Aperta
#1,470 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@tombeckenham ci sta già lavorando.

Dal 23/9/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

has-pr waiting-on: maintainer
TanStack AI version

@tanstack/ai 0.58.0. Also 0.55.0. The code is the same on main.

Framework/Library version

Framework-agnostic (Node 24)

Describe the bug and the steps to reproduce it

A server tool call fails when the handler throws, when the input fails its schema, or when the tool does not exist. chat() streams the TOOL_CALL_RESULT with metadata.tanstack.state: 'output-error'. The client then shows a tool-result part with state: 'error' and error, as the client tools docs describe.

But the tool message that chat() adds to its message history has no error:

{ role: 'tool', content: '{"error":"lookup is down"}', toolCallId: 'call_1' }

Middleware reads that history in onFinish, and @tanstack/ai-persistence saves it. On a reload, modelMessagesToUIMessages gives the tool-result part state: 'error' only when msg.error is set (messages.ts#L1128-L1141). As a result, the part comes back with state: 'complete' and no error. The UI shows the call as failed while the run streams, and as successful after a reload.

buildToolResultChunks uses result.state to tag the chunk, but not to build the message (index.ts#L3157-L3185).

Steps:

  1. In the linked repo, run npm install && npm run repro. No API key is necessary. A scripted adapter makes the tool call.
  2. For each of the three failures, the script prints the streamed metadata, the saved tool message, and the rebuilt tool-result part. This is the output for the handler that throws:
## handler throws
1. streamed TOOL_CALL_RESULT metadata: { tanstack: { state: 'output-error' } }
2. saved tool message: {
  role: 'tool',
  content: '{"error":"lookup is down"}',
  toolCallId: 'call_1'
}
3. rebuilt tool-result part: { state: 'complete', error: undefined }

Expected: the saved tool message has error, and the rebuilt part is { state: 'error', error: 'lookup is down' }. That is the same state that the stream processor sets live (processor.ts#L1655-L1682).

When result.state === 'output-error', set error on that message. This fixes all three cases in the repro. A PR follows.

Related: #1386 and #1401 are about denied and cancelled calls. #1401 adds toolResultOutcome to their metadata. It does not mark a plain failure. I ran a test of the three cases against the head of #1401, and all three still rebuild as complete. Both change the same block of code.

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

https://github.com/aayushbtw/tanstack-ai-tool-error-repro

Do you intend to try to help solve this bug with your own PR?

Yes, I am also opening a PR that solves the problem along side this issue

Terms & Code of Conduct
  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Lingua principale
TypeScript
Stelle
3.1k
Fork
331
Merge medio
1g 10h
PR unite (30g)
130

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di TanStack/ai

Tutte le issue di TanStack/ai

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.