fix(renderer): prevent render loop stall by re-checking immediateRerenderRequested in loop() finally block - #1279
Open
AH64-dll wants to merge 1 commit into
Open
Conversation
…nderRequested in loop() finally block
AH64-dll
requested review from
Hona,
kommander,
msmps and
simonklee
as code owners
July 19, 2026 19:59
AH64-dll
added a commit
to AH64-dll/opencode
that referenced
this pull request
Jul 19, 2026
Updates @opentui/core to include the fix for the render loop race condition where immediateRerenderRequested could be set between the scheduling decision and the finally block, causing the render loop to silently stall. See: anomalyco/opentui#1279
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The render loop can silently stall in idle mode (
_isRunning = false) when arequestRender()call arrives in the window between theif/elsescheduling decision and thefinallyblock that setsthis.rendering = false.Race condition
loop()runs, at the scheduling decision sees_isRunning = falseandimmediateRerenderRequested = false-> goes toelsebranch, clears timeout, schedules nothingelsebranch and thefinallyblock, arequestRender()fires --renderingis stilltrue-> only setsimmediateRerenderRequested = trueand returns early (line 1507-1509)finallysetsthis.rendering = falsebut does not checkimmediateRerenderRequestedactivateFrame()finally setsthis.updateScheduled = falserequestRender()This manifests as the TUI going black during burst event processing (e.g. when the user presses Enter to submit a prompt and the agent starts working).
Fix
In
loop()'sfinallyblock, re-checkimmediateRerenderRequested. If it was set during the race window (after the scheduling decision but beforerendering = false), re-issue viasetImmediate.setImmediate(notprocess.nextTick) is needed becauseactivateFrame()keepsupdateScheduled = trueuntil its ownfinallyafterloop()returns.process.nextTickfires before microtasks resume -- beforeactivateFrame's finally -- sorequestRender()would be blocked by the!updateScheduledguard.Related