{"record":{"id":"740f8c333b864969","repo":"FlowiseAI/Flowise","slug":"error-submitting-tool-outputs-thread-id-thread","errorCode":null,"errorMessage":"Error submitting tool outputs. Thread ID: ${threadId}. Run ID: ${runThreadId}","messagePattern":"Error submitting tool outputs\\. Thread ID: (.+?)\\. Run ID: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/agents/OpenAIAssistant/OpenAIAssistant.ts","lineNumber":622,"sourceCode":"                                    chatId,\n                                    options,\n                                    input,\n                                    usedTools,\n                                    text,\n                                    isStreamingStarted\n                                })\n                                text = result.text\n                                isStreamingStarted = result.isStreamingStarted\n                            } catch (error) {\n                                console.error('Error submitting tool outputs:', error)\n                                await openai.beta.threads.runs.cancel(runThreadId, { thread_id: threadId })\n\n                                const errMsg = `Error submitting tool outputs. Thread ID: ${threadId}. Run ID: ${runThreadId}`\n\n                                await analyticHandlers.onLLMError(llmIds, errMsg)\n                                await analyticHandlers.onChainError(parentIds, errMsg, true)\n\n                                throw new Error(errMsg)\n                            }\n                        }\n                    }\n                }\n\n                // List messages\n                const messages = await openai.beta.threads.messages.list(threadId)\n                const messageData = messages.data ?? []\n                const assistantMessages = messageData.filter((msg) => msg.role === 'assistant')\n                if (!assistantMessages.length) return ''\n\n                // Remove images from the logging text\n                let llmOutput = text.replace(imageRegex, '')\n                llmOutput = llmOutput.replace('<br/>', '')\n\n                await analyticHandlers.onLLMEnd(llmIds, llmOutput)\n                await analyticHandlers.onChainEnd(parentIds, messageData, true)\n                return {","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/agents/OpenAIAssistant/OpenAIAssistant.ts#L604-L640","documentation":"After tools execute, their outputs are submitted back to the OpenAI run via handleToolSubmission. If that submission call fails (network, OpenAI 4xx/5xx, run already expired/cancelled), the code cancels the run, reports onLLMError/onChainError, and throws this message. The original submission error is logged but not in the thrown message.","triggerScenarios":"openai.beta.threads.runs.submitToolOutputs (or the stream) returns an error; the runThreadId is no longer active (expired, already cancelled); rate limit (429); network failure mid-submission.","commonSituations":"Tool took too long so the run expired before submission; OpenAI rate limit; transient network blip; concurrent modification/cancellation of the thread.","solutions":["Read server logs for `Error submitting tool outputs:` which prints the underlying error.","Make tools faster so submission happens before the run expires (~10 min limit).","For 429s, reduce concurrency or add backoff; for 5xx, retry the run.","Ensure the thread/run is not being cancelled elsewhere concurrently.","Patch the message to include the cause for easier triage."],"exampleFix":"// before\n                                const errMsg = `Error submitting tool outputs. Thread ID: ${threadId}. Run ID: ${runThreadId}`\n// after\n                                const errMsg = `Error submitting tool outputs. Thread ID: ${threadId}. Run ID: ${runThreadId}. Cause: ${error instanceof Error ? error.message : String(error)}`","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for (let attempt = 0; attempt < 3; attempt++) {\n  try {\n    return await assistantNode.run(nodeData, input, options)\n  } catch (e) {\n    if ((e as Error).message.startsWith('Error submitting tool outputs.') && attempt < 2) {\n      await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt)); continue\n    }\n    throw e\n  }\n}","preventionTips":["Keep tool execution well under the OpenAI run lifetime (~10 min).","Reduce concurrency to avoid 429s on submission.","Avoid concurrent cancellation of the same thread/run.","Use streaming submission to surface failures earlier."],"tags":["agent","openai-assistant","tool-submission","network","run-expired"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}