Skip to content

Commit 7b2bc18

Browse files
committed
fix(files): destroy the agent shadow deterministically on settle
Cursor round 1 (Low): endAgentStream ran inside runOffRender, whose microtask is dropped when a rapid follow-up stream bumps the run token — leaking the shadow Y.Doc. Split it out into an unguarded microtask queued after the (droppable) final apply, so the shadow is always destroyed.
1 parent 240e314 commit 7b2bc18

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/rich-markdown-editor.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -921,13 +921,20 @@ export function LoadedRichMarkdownEditor({
921921
const finalBody = splitFrontmatter(content).body
922922
const session = agentStreamSessionRef.current
923923
agentStreamSessionRef.current = null
924-
runOffRender(() => {
925-
if (session && finalBody !== lastSyncedBodyRef.current) {
926-
if (applyAgentStreamFrame(editor, session, finalBody))
924+
if (session) {
925+
runOffRender(() => {
926+
if (
927+
finalBody !== lastSyncedBodyRef.current &&
928+
applyAgentStreamFrame(editor, session, finalBody)
929+
) {
927930
lastSyncedBodyRef.current = finalBody
928-
}
929-
if (session) endAgentStream(session)
930-
})
931+
}
932+
})
933+
// Free the shadow with an UNGUARDED microtask (not `runOffRender`): a rapid follow-up stream
934+
// can supersede the run token and drop the apply above, but the shadow must always be
935+
// destroyed. Queued after the apply, so it frees the shadow only once that has had its chance.
936+
queueMicrotask(() => endAgentStream(session))
937+
}
931938
}
932939
return
933940
}

0 commit comments

Comments
 (0)