{"record":{"id":"3f274ad9cb8f2abb","repo":"wavetermdev/waveterm","slug":"tool-call-with-id-s-not-found-in-chat-s","errorCode":null,"errorMessage":"tool call with ID %s not found in chat %s","messagePattern":"tool call with ID (.+?) not found in chat (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/anthropic/anthropic-convertmessage.go","lineNumber":901,"sourceCode":"\t\t\tif block.Type != \"tool_use\" || block.ID != toolCallId {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tupdatedMsg := &anthropicChatMessage{\n\t\t\t\tMessageId: chatMsg.MessageId,\n\t\t\t\tUsage:     chatMsg.Usage,\n\t\t\t\tRole:      chatMsg.Role,\n\t\t\t\tContent:   slices.Clone(chatMsg.Content),\n\t\t\t}\n\t\t\tupdatedMsg.Content[i].ToolUseData = &toolUseData\n\t\t\taiOpts := &uctypes.AIOptsType{\n\t\t\t\tAPIType:    chat.APIType,\n\t\t\t\tModel:      chat.Model,\n\t\t\t\tAPIVersion: chat.APIVersion,\n\t\t\t}\n\t\t\treturn chatstore.DefaultChatStore.PostMessage(chatId, aiOpts, updatedMsg)\n\t\t}\n\t}\n\treturn fmt.Errorf(\"tool call with ID %s not found in chat %s\", toolCallId, chatId)\n}\n\nfunc RemoveToolUseCall(chatId string, toolCallId string) error {\n\tchat := chatstore.DefaultChatStore.Get(chatId)\n\tif chat == nil {\n\t\treturn fmt.Errorf(\"chat not found: %s\", chatId)\n\t}\n\tfor _, genMsg := range chat.NativeMessages {\n\t\tchatMsg, ok := genMsg.(*anthropicChatMessage)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tfor i, block := range chatMsg.Content {\n\t\t\tif block.Type != \"tool_use\" || block.ID != toolCallId {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tupdatedMsg := &anthropicChatMessage{\n\t\t\t\tMessageId: chatMsg.MessageId,","sourceCodeStart":883,"sourceCodeEnd":919,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/anthropic/anthropic-convertmessage.go#L883-L919","documentation":"After locating the chat, UpdateToolUseData scans all native messages for a tool call whose ID matches toolCallId. If the whole chat is traversed without a match, it concludes the tool call does not exist in that chat and returns this error.","triggerScenarios":"UpdateToolUseData called with a toolCallId that no *anthropicChatMessage in the chat contains — the call was already removed (e.g. by RemoveToolUseCall), the ID belongs to another chat, or the ID was fabricated.","commonSituations":"Double-applying an update after the tool use was removed; mixing up IDs between concurrent chats; using a truncated/renamed tool call ID from logs.","solutions":["Confirm the toolCallId exists in this chat's messages (it may have been removed by RemoveToolUseCall)","Use the exact tool_use id from the assistant message's tool_use block","Check you are passing the correct chatId for that tool call"],"exampleFix":"// before\nerr := anthropic.UpdateToolUseData(chatId, staleToolCallID, data)\n// after\nif err := anthropic.UpdateToolUseData(chatId, toolCallID, data); err != nil {\n    // skip or recreate the tool use instead of failing\n    log.Printf(\"tool call %s gone, skipping update\", toolCallID)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := anthropic.UpdateToolUseData(chatId, toolCallId, data)\nif err != nil && strings.Contains(err.Error(), \"not found in chat\") {\n    // tool use already removed or wrong chat; log and continue\n    log.Printf(\"tool call %s not in chat %s; skipping\", toolCallId, chatId)\n    return nil\n}","preventionTips":["Track live tool call IDs per chat so you never update removed ones","Make update/remove operations idempotent in your wrapper layer","Use the exact tool_use id from the assistant message, not a derived value"],"tags":["go","anthropic","tool-use","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}