You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: t3_pending_request_respond reports "not found" for an answer it applied #19984
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
In a Pi-provider thread, an extension tool calls ctx.ui.select(...). T3 shows it as a pending user_input_request.
From another thread, an agent reads it with t3_pending_request_read and answers with t3_pending_request_respond, using the question id and one of the offered option values.
Expected behavior
The call succeeds and the answer reaches the tool. If the request was already answered, the error says that, for example "already answered", not "not found".
Actual behavior
t3_pending_request_respond failed with:
{"_tag":"OrchestratorMcpFailure","code":"invalid_request","message":"The pending user-input request was not found."}
Yet the thread shows the request completed at the same moment, with the exact option sent (large — xhigh thinking), and the tool received that answer. An agent that trusts the error retries, or reports a failure that did not happen. A later t3_pending_request_respond in another thread succeeded normally ({"sequence": …}), so this looks like a race between applying the answer and building the response.
Impact
Minor bug or occasional failure
Version or commit
0.0.46-nightly.20261014.3105
Environment
Linux x64, desktop. Pi provider (Pi 1.2.0). The caller was a Claude-provider thread using the T3 MCP tools.
Thanks for the report. On current main, the call that returned this error could not have applied the answer, so the race described here doesn't match the code.
In apps/server/src/mcp/toolkits/thread/handlers.ts, t3_pending_request_respond first calls readQuestion, which looks up the request and only accepts it while its status is pending. If that lookup fails, it returns "The pending user-input request was not found." and stops there. The runtime-request.respond command is dispatched only after the lookup succeeds. So a not-found error means this call never sent an answer, and the request had already left pending by the time the call ran.
That points to something else answering first. It could have been a second t3_pending_request_respond call with the same request id (for example, a client retry after a slow first call), the answer submitted from the UI, or the Pi extension settling the request on its own.
To narrow this down:
Did the calling agent or MCP client send the respond call more than once (retry or timeout) for that request id?
Could anyone have answered the question in the T3 UI at about the same time?
Can you reproduce it with a single respond call? If you can, please share the server log lines for that request id.
Separately, it's fair to ask that an already answered request report "already answered" rather than "not found". The lookup currently treats both cases the same way.
Retries: none. The respond call was made once, by an agent in another thread, and the error came back on that call.
UI: nobody answered in the T3 UI. The human confirms they didn't respond.
More evidence: the same Pi thread asked a second question shortly afterwards (ask_user → ctx.ui.select). It also completed, with the answer "Accept as-is", although neither the human nor any agent called t3_pending_request_respond for it.
So, as you suspected, something other than this call is answering these requests. The candidates are the Pi side settling them itself, or T3 auto-resolving them. The thread was an MCP-launched Pi thread in full-access runtime mode with default interaction mode. The extension tool calls ctx.ui.select(title, options) with no timeout or signal. That would explain the first question too: it was resolved just before the respond call, so the call correctly found nothing pending.
The project has since been deleted, so I can't pull its request records. If auto-resolution of extension UI requests is expected in some mode, a pointer would help; otherwise I'll try to reproduce it with a single question and capture the server log.
The "already answered" vs "not found" distinction you mention would have made this clear immediately.
Follow-up: a single-question repro does not reproduce it.
A fresh MCP-launched Pi thread (full-access, default interaction mode) called the same ask_user tool once (ctx.ui.select with two options). The question showed in the T3 UI, and nobody answered. After 5+ minutes it was still listed by t3_pending_request_list as waiting, and the tool call was still running. So nothing auto-resolves a request in the plain case.
That leaves the two answers in the original thread unexplained. One question received exactly the option my respond call sent, while the call itself returned "not found". The other was answered "Accept as-is" with no respond call and no UI answer. That thread differed in two ways: it ran in a T3 worktree rather than a scratch folder, and the agent asked several questions in a row. Without the request records (the project was deleted) I can't take it further, so I'm fine with this being narrowed to the "already answered" vs "not found" message, or closed. If it recurs, I'll capture the server log for the request id straight away.
Activity
juliusmarminge commentedon Oct 15, 2026
Note
Grok responding on behalf of Julius.
Thanks for the report. On current
main, the call that returned this error could not have applied the answer, so the race described here doesn't match the code.In
apps/server/src/mcp/toolkits/thread/handlers.ts,t3_pending_request_respondfirst callsreadQuestion, which looks up the request and only accepts it while its status ispending. If that lookup fails, it returns "The pending user-input request was not found." and stops there. Theruntime-request.respondcommand is dispatched only after the lookup succeeds. So a not-found error means this call never sent an answer, and the request had already leftpendingby the time the call ran.That points to something else answering first. It could have been a second
t3_pending_request_respondcall with the same request id (for example, a client retry after a slow first call), the answer submitted from the UI, or the Pi extension settling the request on its own.To narrow this down:
Separately, it's fair to ask that an already answered request report "already answered" rather than "not found". The lookup currently treats both cases the same way.
daniel-ballance commentedon Oct 15, 2026
Thanks for the walkthrough. Answers:
ask_user→ctx.ui.select). It also completed, with the answer "Accept as-is", although neither the human nor any agent calledt3_pending_request_respondfor it.So, as you suspected, something other than this call is answering these requests. The candidates are the Pi side settling them itself, or T3 auto-resolving them. The thread was an MCP-launched Pi thread in
full-accessruntime mode with default interaction mode. The extension tool callsctx.ui.select(title, options)with no timeout or signal. That would explain the first question too: it was resolved just before the respond call, so the call correctly found nothing pending.The project has since been deleted, so I can't pull its request records. If auto-resolution of extension UI requests is expected in some mode, a pointer would help; otherwise I'll try to reproduce it with a single question and capture the server log.
The "already answered" vs "not found" distinction you mention would have made this clear immediately.
daniel-ballance commentedon Oct 15, 2026
Follow-up: a single-question repro does not reproduce it.
A fresh MCP-launched Pi thread (
full-access, default interaction mode) called the sameask_usertool once (ctx.ui.selectwith two options). The question showed in the T3 UI, and nobody answered. After 5+ minutes it was still listed byt3_pending_request_listas waiting, and the tool call was still running. So nothing auto-resolves a request in the plain case.That leaves the two answers in the original thread unexplained. One question received exactly the option my respond call sent, while the call itself returned "not found". The other was answered "Accept as-is" with no respond call and no UI answer. That thread differed in two ways: it ran in a T3 worktree rather than a scratch folder, and the agent asked several questions in a row. Without the request records (the project was deleted) I can't take it further, so I'm fine with this being narrowed to the "already answered" vs "not found" message, or closed. If it recurs, I'll capture the server log for the request id straight away.