{"record":{"id":"f044cbab93c70d39","repo":"wavetermdev/waveterm","slug":"function-call-with-callid-s-not-found-in-chat-s","errorCode":null,"errorMessage":"function call with callId %s not found in chat %s","messagePattern":"function call with callId (.+?) not found in chat (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-backend.go","lineNumber":439,"sourceCode":"\t\t}\n\n\t\tif chatMsg.FunctionCall != nil && chatMsg.FunctionCall.CallId == callId {\n\t\t\tupdatedMsg := *chatMsg\n\t\t\tupdatedFunctionCall := *chatMsg.FunctionCall\n\t\t\tupdatedFunctionCall.ToolUseData = &newToolUseData\n\t\t\tupdatedMsg.FunctionCall = &updatedFunctionCall\n\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\n\t\t\treturn chatstore.DefaultChatStore.PostMessage(chatId, aiOpts, &updatedMsg)\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"function call with callId %s not found in chat %s\", callId, chatId)\n}\n\nfunc RemoveToolUseCall(chatId string, callId 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\n\tfor _, genMsg := range chat.NativeMessages {\n\t\tchatMsg, ok := genMsg.(*OpenAIChatMessage)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tif chatMsg.FunctionCall != nil && chatMsg.FunctionCall.CallId == callId {\n\t\t\tchatstore.DefaultChatStore.RemoveMessage(chatId, chatMsg.MessageId)\n\t\t\treturn nil\n\t\t}","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-backend.go#L421-L457","documentation":"UpdateToolUseData scanned all OpenAIChatMessage entries in the chat's NativeMessages and found no FunctionCall whose CallId matches the given callId, at openai-backend.go:439. The chat exists but the specific tool-call item does not.","triggerScenarios":"Calling UpdateToolUseData with a callId that was never issued in this chat, a callId belonging to another chat, a callId already removed via RemoveToolUseCall, or a callId whose message is stored as a non-OpenAI message (skipped via the ok-continue path).","commonSituations":"Tool result arrives after the call was cancelled/deleted; retrying an update after a first attempt already removed the message; ids mixed across concurrent chats; backend restarted losing in-flight call records.","solutions":["Confirm the callId came from the current chat's streaming response (match FunctionCall.CallId)","Check the chat still contains the function-call message: enumerate chat.NativeMessages and search for the callId before updating","Treat this as terminal for that callId: skip the update or re-post the tool output as a new message instead of retrying","Ensure you are using the callId (tool_call id from the model), not the message/item id"],"exampleFix":"// before\nerr := UpdateToolUseData(chatId, callId, toolData) // panics on not-found\n// after\nif err := UpdateToolUseData(chatId, callId, toolData); err != nil {\n    log.Printf(\"skip tool update (call gone): %v\", err)\n    return nil // do not retry\n}","handlingStrategy":"validation","validationCode":"chat := chatstore.DefaultChatStore.Get(chatId)\nif chat != nil {\n    found := false\n    for _, m := range chat.NativeMessages {\n        if cm, ok := m.(*OpenAIChatMessage); ok && cm.FunctionCall != nil && cm.FunctionCall.CallId == callId {\n            found = true\n            break\n        }\n    }\n    if !found {\n        return nil // callId no longer present; skip update\n    }\n}","typeGuard":"func findFunctionCall(chatId, callId string) *OpenAIChatMessage {\n    chat := chatstore.DefaultChatStore.Get(chatId)\n    if chat == nil {\n        return nil\n    }\n    for _, m := range chat.NativeMessages {\n        if cm, ok := m.(*OpenAIChatMessage); ok && cm.FunctionCall != nil && cm.FunctionCall.CallId == callId {\n            return cm\n        }\n    }\n    return nil\n}","tryCatchPattern":"if err := UpdateToolUseData(chatId, callId, data); err != nil {\n    if strings.Contains(err.Error(), \"not found in chat\") {\n        log.Printf(\"tool call %s gone; dropping update\", callId)\n        return nil\n    }\n    return err\n}","preventionTips":["Only call updates with callIds from the live streaming response of that chat","Don't retry updates after RemoveToolUseCall succeeded","Use the model-issued call_id, not message ids","Handle cancelled/interrupted tool calls idempotently (missing = done)"],"tags":["go","tool-use","openai","state"],"backgroundTag":"tool-call-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}