Skip to content

Conversation

@code-yeongyu
Copy link
Contributor

@code-yeongyu code-yeongyu commented Dec 4, 2025

Problem

In TUI mode, a race condition occurs in environments where initialization involves significant latency (e.g., SSH, WSL2, remote VSCode).

The checkUpgrade function is scheduled to execute after 1 second. If the TUI initialization phase takes longer than 1 second, checkUpgrade executes first. Previously, checkUpgrade called Instance.provide() without passing the init (InstanceBootstrap) object.

Found this and fixed this using my personal plugin oh-my-opencode, but i thought there is no ai slop for this and found the real cause and fixed so I made this PR.

Root Cause

The Instance.provide() method follows a singleton pattern with caching.

  1. checkUpgrade executes and calls Instance.provide() (without init).
  2. An Instance is created using default settings without executing configuration or event hooks, and this uninitialized instance is cached.
  3. When the main TUI logic eventually calls Instance.provide(init), the system detects the cached instance.
  4. It returns the existing (poisoned) instance, effectively ignoring the provided init object.

Impact:

  • Config hooks are skipped -> Custom agents defined on plugin are not registered.
  • Event hooks are skipped -> Plugins do not receive events.

Solution

Updated checkUpgrade in packages/opencode/src/cli/cmd/tui/worker.ts to accept and pass the init: InstanceBootstrap object.

Now, regardless of whether checkUpgrade or the main TUI loop wins the race to create the Instance, the singleton is guaranteed to be initialized with the correct configuration and hooks.

Reproduction

  1. Run OpenCode TUI in a constrained environment (or inject artificial delay in TUI startup > 1s).
  2. Observe that checkUpgrade runs.
  3. Verify that custom agents defined in config are missing or event handlers are not triggering.

Related

Closes #4846

@code-yeongyu code-yeongyu force-pushed the fix/tui-plugin-hooks-idempotent branch from 7dfd48a to aa371dd Compare December 4, 2025 02:44
@rekram1-node
Copy link
Collaborator

@code-yeongyu is the issue actually w/ plugin init? Or is the issue with how check upgrade is working? Because it kinda sounds like the later but maybe I misunderstand the issue

@code-yeongyu code-yeongyu force-pushed the fix/tui-plugin-hooks-idempotent branch from aa371dd to 2cf2805 Compare December 4, 2025 04:12
@code-yeongyu
Copy link
Contributor Author

You're right. I initially misunderstood the flow and tried to make Plugin.init() idempotent. But as you said, the issue was actually in how checkUpgrade works. I've updated the code to pass init: InstanceBootstrap to checkUpgrade now.

@rekram1-node rekram1-node changed the title fix(plugin): make init idempotent to handle race fix: ensure checkUpgrade sets init: Dec 4, 2025
@rekram1-node rekram1-node merged commit 5a9f4e5 into sst:dev Dec 4, 2025
2 of 3 checks passed
@rekram1-node
Copy link
Collaborator

good find, thanks!

kcrommett added a commit to Latitudes-Dev/shuvcode that referenced this pull request Dec 4, 2025
* fix: ensure checkUpgrade sets `init:` (sst#5040)

* chore: format code

* ci: use blacksmith runners in review workflow too (sst#5042)

* zen: make session provider sticky

* ci: only maintainer can trigger

* ci: cleaner

* ignore: update download stats 2025-12-04

* fix(tui): cursor color

* Preserve prompt input when creating new session (sst#4993)

* fix: model not being passed correctly to tool

* tweak: bash tool messages regarding timeouts and truncation more clear for agent (sst#5066)

* tui: fix /new slash command being persisted in prompt input

* add optional prompt Input to Github Action (sst#4828)

Co-authored-by: Github Action <action@github.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>

* bump: builtin plugin versions

* feat: Add SAP AI Core provider support (sst#5023)

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>

* core: ensure model npm package falls back to dev models config when not explicitly defined

* docs: add CodeCompanion.nvim integration instructions (sst#5079)

* tweak: bash tool description re commit stuff

* core: add test for custom model npm package inheritance

* feat(desktop): terminal pane (sst#5081)

Co-authored-by: Github Action <action@github.com>
Co-authored-by: Dax Raad <d@ironbay.co>

* Revert "feat(desktop): terminal pane (sst#5081)"

This reverts commit d763c11.

* release: v1.0.133

* sync: record last synced tag v1.0.133

---------

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
Co-authored-by: YeonGyu-Kim <code.yeon.gyu@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: wsx99outlook <247713593+wsx99outlook@users.noreply.github.com>
Co-authored-by: Frank <frank@sst.dev>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
Co-authored-by: Daniel Gray <DanielFGray@gmail.com>
Co-authored-by: Shantur Rathore <i@shantur.com>
Co-authored-by: Daniel Polito <danielbpolito@gmail.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: Cason Adams <casonadams@gmail.com>
Co-authored-by: opencode <opencode@sst.dev>
kcrommett added a commit to Latitudes-Dev/shuvcode that referenced this pull request Dec 5, 2025
* fix: ensure checkUpgrade sets `init:` (sst#5040)

* chore: format code

* ci: use blacksmith runners in review workflow too (sst#5042)

* zen: make session provider sticky

* ci: only maintainer can trigger

* ci: cleaner

* ignore: update download stats 2025-12-04

* fix(tui): cursor color

* Preserve prompt input when creating new session (sst#4993)

* fix: model not being passed correctly to tool

* tweak: bash tool messages regarding timeouts and truncation more clear for agent (sst#5066)

* tui: fix /new slash command being persisted in prompt input

* add optional prompt Input to Github Action (sst#4828)

Co-authored-by: Github Action <action@github.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>

* bump: builtin plugin versions

* feat: Add SAP AI Core provider support (sst#5023)

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>

* core: ensure model npm package falls back to dev models config when not explicitly defined

* docs: add CodeCompanion.nvim integration instructions (sst#5079)

* tweak: bash tool description re commit stuff

* core: add test for custom model npm package inheritance

* feat(desktop): terminal pane (sst#5081)

Co-authored-by: Github Action <action@github.com>
Co-authored-by: Dax Raad <d@ironbay.co>

* Revert "feat(desktop): terminal pane (sst#5081)"

This reverts commit d763c11.

* release: v1.0.133

* Update Nix flake.lock and hashes

* Reapply "feat(desktop): terminal pane (sst#5081)"

This reverts commit f9dcd97.

* chore: format code

* Update Nix flake.lock and hashes

* zen: fix byok

* ignore: fix provider credentials query for BYOK

Provider credentials field was being selected from ProviderTable even when the table wasn't joined (when byokProvider was undefined). Now the join is conditional - when byokProvider exists, we join and get the credentials; when it doesn't, the join condition is always false so provider remains null.

* docs: llama.cpp docs: `limit` moved under model (sst#5089)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>

* fix: add getModel to SAP AI Core provider for correct SDK initialization (sst#5086)

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>

* fix pty builds

* fix

* increase default scroll speed

* ci: review

* fix: ensure that vcs is still set to git even if no commits in repo

* ignore: rm slop commnand (only for opencode repo this isnt shipping)

* chore: format code

* ignore: cmd tweak

* tui: wrap dialog option descriptions (sst#5083)

* ci: keybinds

* fix: ensure projects that go from having no commits to having commits have sessions migrated (sst#5105)

Co-authored-by: GitHub Action <action@github.com>

* ignore: tweak

* ignore: update download stats 2025-12-05

* Zen: add codex max

* do not use required pty for local dev

* fix: sst#5064 ProviderInitError github-copilot-enterprise (sst#5123)

* feat(theme): Vercel (sst#5119)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>

* fix(desktop): new session not selecting tab

* fix(desktop): clone pty session on reconnect

* add experimental.open_telemetry config option to enable OTEL spans (sst#4978)

Co-authored-by: noamzbr <noamzbr@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>

* ignore: regen sdk

* fix(desktop): prompting

* fix(desktop): terminal cursor position

* feat: add max steps for supervisor and sub-agents (sst#4062)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>

* tweak: bash tool improve output metadata for agent consumption, fix small timeout issue (sst#5131)

* OpenCode Desktop app (sst#5044)

Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>

* Update Nix flake.lock and hashes

* release: v1.0.134

* sync: record last synced tag v1.0.134

* chore: format code

---------

Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
Co-authored-by: YeonGyu-Kim <code.yeon.gyu@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: wsx99outlook <247713593+wsx99outlook@users.noreply.github.com>
Co-authored-by: Frank <frank@sst.dev>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
Co-authored-by: Daniel Gray <DanielFGray@gmail.com>
Co-authored-by: Shantur Rathore <i@shantur.com>
Co-authored-by: Daniel Polito <danielbpolito@gmail.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: Cason Adams <casonadams@gmail.com>
Co-authored-by: opencode <opencode@sst.dev>
Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: ry2009 <134240944+ry2009@users.noreply.github.com>
Co-authored-by: Julian Visser <12615757+justmejulian@users.noreply.github.com>
Co-authored-by: Anthony Shew <anthonyshew@gmail.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
Co-authored-by: Noam Bressler <noamzbr@gmail.com>
Co-authored-by: noamzbr <noamzbr@users.noreply.github.com>
Co-authored-by: Nathan Thomas <nwthomas@me.com>
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Notification plugin from docs doesn't work

2 participants