Repository navigation
[Bug]: Cursor run continues after T3 marks parent and native subagents failed #15447
Description
Before submitting
- I searched existing issues and did not find an exact duplicate.
- I included enough detail to investigate the problem; a deterministic minimal reproduction is not yet available.
Area
apps/server
Steps to reproduce
Observed sequence, rather than a deterministic minimal reproduction:
- Use the Cursor provider in the T3 Code desktop nightly listed below.
- Start an agent task that launches native subagents and leave it running.
- In the affected run, T3 marked the parent and four unfinished native subagent tasks failed immediately after another native subagent completed.
- Inspect the persisted orchestration events and Cursor provider protocol logs: the same native Cursor run keeps emitting updates after T3 has marked it failed.
The initial exception is not available in the retained logs, so I cannot identify the exact input/event that triggers this yet.
Expected behavior
T3's run status should agree with the provider's lifecycle. If event ingestion fails and T3 terminates the app run, it should cancel the underlying provider run and its owned work, or recover the event subscription. The original exception should remain available for diagnosis.
Actual behavior
The thread displayed Provider turn failed. and recorded a terminal failure, while the underlying Cursor run continued for at least another 71 minutes. T3 also marked four unfinished native subagent tasks failed at the same instant.
This makes it difficult to know whether work has stopped and risks overlapping work if the user retries. A later retry also failed to start, but its underlying cause was not recovered, so I am not claiming it was definitively caused by the lingering run.
Impact
Major degradation or frequent failure
Version or commit
0.0.46-nightly.20261003.2638
Environment
- T3 Code desktop app, Linux x86_64, Nobara/Fedora 44, KDE Wayland
- Kernel
7.2.6-201.nobara.fc44.x86_64 - Cursor provider; installed server bundle uses
@cursor/sdkfor this run path - Cursor CLI on PATH:
2026.08.04-aaa8809(version/help/auth status work; this is not evidence that the SDK uses that binary)
Logs or stack traces
Sanitized timeline from the local orchestration database and provider logs; all times UTC:
2026-10-04T02:07:06.054Z native subagent node.completed
2026-10-04T02:07:06.060Z subagent.completed
2026-10-04T02:07:06.064Z turn-item.completed
2026-10-04T02:07:06.423Z app parent run + 4 unfinished native subagent tasks marked failed
message: "Provider turn failed."
class: "unknown", code: null, retryable: null
2026-10-04T03:18:11.141Z last observed update for the SAME native Cursor run
There were 12,896 provider protocol updates for that same native run after the app failure, counted across the affected provider log and its two rotated files. No run.completed for that native run was found in those retained files. The app failure occurred at 19:07 PDT on October 3.
No OS OOM kill or associated core dump was found in the inspected records. This is an app/provider lifecycle mismatch; it does not establish whether there was transient memory pressure before the failure.
Suspected failure path (not a confirmed original exception)
Inspection of the installed server bundle shows the provider-event consumer's catchCause path in RunExecutionService:
- Logs
orchestration V2 provider event ingestion failed. - Calls
writeFinalRunEventswith a failed terminal of classunknownandopenRunOwnedSubagents. - Closes
eventSubscription. - Does not call provider interrupt/cancel in that catch path.
That path matches the persisted failure shape and the continued native traffic. However, the warning with the original cause was not found in the retained logs, so the exact triggering exception remains unconfirmed.
Related reports
- [Bug]: Claude AskUserQuestion with a blank option description fails the run and wedges the thread #15316 describes the same failure-without-provider-interruption behavior for a specific Claude
AskUserQuestionschema error. This report adds evidence from Cursor with native subagents; the Claude-specific trigger has not been established here. - [Bug]: Getting error during cursor runs,
RetriableError: [canceled] http/2 stream closed with error code CANCEL (0x8)#12374 is a different Cursor transport failure on an earlier version. - [Bug]: Cursor ACP backgrounds a shell, ends the turn, and never comes back #13284 and fix(server): Cursor adapter turn-lifecycle hardening (races, missing terminal events, lock retention) #9047 concern the older Cursor ACP path and different lifecycle problems.
Workaround
No reliable workaround verified. A system restart did not prevent a subsequent provider failure. No settings or source changes were made during this investigation.
Raw logs, prompts, credentials, and project contents are intentionally omitted. This report was prepared with Codex from local read-only diagnostics and posted at the affected user's request.
Activity
juliusmarminge commentedon Oct 4, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks for the careful timeline and bundle notes, @j0nsh1n. This is a real lifecycle bug, and it's still present on current
main(737993303d). No commit since your nightly changes this path.What I found
The stored terminal matches the ingestion-failure write in
RunExecutionService, not a Cursor adapter terminal. ThecatchCausearound the provider-event consumer logsorchestration V2 provider event ingestion failedwith the real cause, then callswriteFinalRunEvents.makeProviderFailureonly keeps a specific message for a handful of error tags, so anything else (a schema error, for example) becomes the genericProvider turn failed.with classunknown, and the thread never shows the actual exception.writeFinalRunEventsthen runscascadeTerminalizeRunOwnedSubagents, which marks every still-open run-owned subagent, node and turn item failed in the same write. That explains the parent and four unfinished subagents failing together, while the one that had just completed was already settled.The Cursor run keeps going because that path never cancels it:
subscribeEvents, so closingeventSubscriptiondoes nothing.interruptTurnis what callsrun.cancel, and the failure path doesn't call it.activeTurnstays set until the SDK run actually finishes.This also likely explains the failed retry. The synthetic terminal makes the thread look reusable, but the next send hits
CursorAdapterV2.startTurn's guard (Cursor provider turn … is still active) before anything cancels the old run. Stop isn't offered either, because the run is already markedfailed. For now, quitting the desktop app closes the Cursor session, which is the practical way to drop the leftover turn.#15316 is the same ingestion-failure finalization gap with a Claude
AskUserQuestiontrigger. #12374, #13284 and #9047 are different paths.Likely fix area
RunExecutionService's ingestion-failure path. Some options:run.cancel).A maintainer will decide on the fix direction.
topitopongsala commentedon Oct 16, 2026
Another datapoint on
0.0.46-nightly.20261011.2994(Linux x86_64, Cursor provider,grok-4.7). Here T3 marked the run cancelled, not failed, and the next turn could not start. This is the case the issue leaves open: "A later retry also failed to start".Timeline from the Cursor provider protocol log and the run projections (UTC, 2026-10-15):
So the native run worked for another 110 minutes after T3 cancelled the app run. It ran shell commands, and it wrote state outside T3. None of that output was shown. The provider log contains no
run.cancelevent for this agent. InCursorAdapterV2.interruptTurn,if (context === null && turnInput.requestRuntimeRestart === true) return;returns with no cancel. This may be the path that ran, but I cannot prove it from the retained logs.The failed run 21 then left the thread stuck through the missed-run handoff budget (#19875). Every later turn failed with "Insufficient context allowance", so this bug has a larger effect on Cursor threads than one lost turn.
Expected: T3 sends
run.cancelfor the native run, or does not mark the app run terminal while the native run is live. A newrun.startshould not be sent to an agent whose previous run is still running, or it should go through the existinglistRuns/cancelRunrecovery instartRun.