Skip to content

fix: resolve SideEffectNotAllowedException in intention previews#11894

Merged
RomneyDa merged 2 commits intomainfrom
side-effects
Mar 26, 2026
Merged

fix: resolve SideEffectNotAllowedException in intention previews#11894
RomneyDa merged 2 commits intomainfrom
side-effects

Conversation

@RomneyDa
Copy link
Copy Markdown
Contributor

@RomneyDa RomneyDa commented Mar 26, 2026

Summary

  • Fixes SideEffectNotAllowedException thrown during JetBrains intention preview computation (autocomplete, inspections)
  • Changes Dispatchers.Main to Dispatchers.Default in DocumentChangeTracker and ActiveHandlerManager coroutine scopes
  • Dispatchers.Main schedules work via INVOKE_LATER, which JetBrains forbids during preview computation; neither class requires EDT for its coroutine work

Fixes #9463, #8035

Test plan

  • Verify autocomplete/intention previews no longer throw SideEffectNotAllowedException
  • Verify typing session detection still works correctly
  • Verify cursor movement handling and next-edit chain deletion still function as expected

Summary by cubic

Prevent SideEffectNotAllowedException in JetBrains intention previews by moving coroutine work off the EDT while keeping handlers single-threaded. Switched Dispatchers.Main to Dispatchers.Default.limitedParallelism(1) to keep autocomplete and inspections stable and avoid race conditions.

Written for commit 911240a. Summary will update on new commits.

…n JetBrains intention previews

DocumentChangeTracker and ActiveHandlerManager used Dispatchers.Main which
schedules work via INVOKE_LATER. JetBrains forbids this during intention
preview computation (autocomplete, inspections), throwing
SideEffectNotAllowedException. Neither class requires EDT for its coroutine
work, so switching to Dispatchers.Default resolves the issue.

Fixes #9463, #8035
@RomneyDa RomneyDa requested a review from a team as a code owner March 26, 2026 18:48
@RomneyDa RomneyDa requested review from sestinj and removed request for a team March 26, 2026 18:48
@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Mar 26, 2026
@continue
Copy link
Copy Markdown
Contributor

continue bot commented Mar 26, 2026

Docs Review: No documentation updates needed.

This PR is an internal bug fix that changes coroutine dispatchers from Dispatchers.Main to Dispatchers.Default in the IntelliJ extension to resolve a SideEffectNotAllowedException. This is a low-level threading fix that doesn't affect user-facing functionality, configuration options, or APIs—no docs changes required.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Dispatchers.Default allows concurrent execution on a thread pool,
which breaks thread-safety for shared mutable state that was previously
serialized on the Main/EDT dispatcher. Using limitedParallelism(1)
preserves single-threaded execution while still avoiding the
SideEffectNotAllowedException from Dispatchers.Main.
@RomneyDa RomneyDa marked this pull request as draft March 26, 2026 20:57
@RomneyDa RomneyDa marked this pull request as ready for review March 26, 2026 21:24
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/listeners/ActiveHandlerManager.kt">

<violation number="1" location="extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/listeners/ActiveHandlerManager.kt:59">
P1: Switching this scope to `Dispatchers.Default` introduces unsynchronized cross-thread access to `ActiveHandlerManager` state, which can race handler activation/clearing against cursor-event processing.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

class ActiveHandlerManager(private val project: Project) : SelectionListener, CaretListener, DumbAware {

private val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private val coroutineScope = CoroutineScope(Dispatchers.Default.limitedParallelism(1) + SupervisorJob())
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Switching this scope to Dispatchers.Default introduces unsynchronized cross-thread access to ActiveHandlerManager state, which can race handler activation/clearing against cursor-event processing.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/listeners/ActiveHandlerManager.kt, line 59:

<comment>Switching this scope to `Dispatchers.Default` introduces unsynchronized cross-thread access to `ActiveHandlerManager` state, which can race handler activation/clearing against cursor-event processing.</comment>

<file context>
@@ -56,7 +56,7 @@ interface CursorMovementHandler {
 class ActiveHandlerManager(private val project: Project) : SelectionListener, CaretListener, DumbAware {
 
-    private val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
+    private val coroutineScope = CoroutineScope(Dispatchers.Default.limitedParallelism(1) + SupervisorJob())
     private var activeHandler: CursorMovementHandler? = null
     private var isHandlingEvent = false
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed this closely and seems alright.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it—thanks for checking.

@github-project-automation github-project-automation bot moved this from Todo to In Progress in Issues and PRs Mar 26, 2026
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Mar 26, 2026
@RomneyDa RomneyDa merged commit 581980e into main Mar 26, 2026
79 of 82 checks passed
@RomneyDa RomneyDa deleted the side-effects branch March 26, 2026 21:37
@github-project-automation github-project-automation bot moved this from In Progress to Done in Issues and PRs Mar 26, 2026
@github-actions github-actions bot locked and limited conversation to collaborators Mar 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

lgtm This PR has been approved by a maintainer size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Plugin stops working because of Side effect

2 participants