Skip to content

fix(settings): stop engine reloads on settings open (MCP re-mint, provider-sync race, workspace re-select) - #2544

Merged
benjaminshafii merged 1 commit into
devfrom
fix/settings-open-engine-reloads
Jul 7, 2026
Merged

fix(settings): stop engine reloads on settings open (MCP re-mint, provider-sync race, workspace re-select)#2544
benjaminshafii merged 1 commit into
devfrom
fix/settings-open-engine-reloads

Conversation

@benjaminshafii

Copy link
Copy Markdown
Member

Summary

Follow-up to #2530 (the provider-sync engine dispose/create loop). This fixes the remaining family the same customer reported: the OpenCode engine reloads when the Settings screen opens (and when clicking the current workspace in the settings menu). All three paths were identified by code-tracing every settings-mount effect, then verified live on the same Daytona repro rig as #2530 (seeded Acme Robotics cloud, signed in as alex@acme.test, org provider imported, openwork-cloud MCP stuck failed — matching the customer's failing-MCP environment).

The three paths

  1. Cloud MCP re-mint on every settings opensyncCloudControlMcp (mounted only by the settings route) re-mints the openwork-cloud MCP token when the entry is unhealthy, guarded to once per unhealthy episode. But the guard (cloudMcpUnhealthyRemintAttempted) was a closure variable in a store recreated on every settings mount, so a persistently unhealthy cloud MCP (revoked org token, blocked URL) re-minted → POST /workspace/:id/mcp → runtime config write → markReloadRequired("mcp")engine reload on every settings open, forever. Fix: persist the attempt marker (org-scoped, openwork.den.mcp.unhealthyRemintAttempt) with the module's existing storage pattern; cleared when the entry reports connected or when the user hits the user-facing Refresh (force).
  2. Provider sync racing target resolution — a cloud-provider sync pass could start before the OpenWork server target resolved; the import-baseline read then silently fell back to an empty source, so the pass re-imported every org provider (observed live: auth PUT + 2× config PATCH + 3 engine disposes with a byte-identical baseline). Fix: performCloudProviderSync now requires the resolved OpenWork server target up front — imports and persistence need it anyway (patchRuntimeProviders throws without it).
  3. Workspace re-select reload — the settings workspace menu had no same-id guard (the session route has one), so clicking the already-active workspace POSTed /workspaces/:id/activate, and the server reloaded the engine unconditionally for local workspaces. Fix: same-id selections return early in the app, and the server skips the reload when the workspace is already first (workspace-switch reloads stay, per [Bug]: Permissions in opencode.jsonc are ignored on every launch #870).

Live verification (before → after, same environment)

settings action before (observed) after (observed)
open #1 MCP re-mint + engine reload MCP re-mint + engine reload — the one allowed per-episode attempt; marker persisted
open #2 spurious full provider re-import: auth PUT + 2× PATCH /config + 3 reloads no writes, no reloads
open #3 MCP re-mint + engine reload again (guard reset by remount) no writes, no reloads
click current workspace in menu POST /workspaces/:id/activate → engine reload no activate call, no reload

Engine instance create-count stayed flat (13 → 13) across opens #2/#3 and the workspace re-select, with the openwork-cloud MCP still genuinely failed. Full request-log evidence: #2530 (comment)

Tests

  • pnpm --filter openwork-server test -- src/workspace-activate.e2e.test.ts src/runtime-config-patch-reload.e2e.test.ts — pass, 7 tests (new: engine stub counts /instance/dispose — activate reloads on switch only, re-activating the active workspace does not)
  • pnpm --filter @openwork/app exec bun test src/react-app/domains/connections/cloud-mcp-user-state.test.ts — pass, 3 tests (episode marker helpers: round-trip, corrupt JSON, clear)
  • pnpm --filter @openwork/app typecheck / pnpm --filter openwork-server typecheck — clean

Screen-recording note: verification was request-log + engine-log based (writes and dispose counts per settings open, tables above); the #2530 fraimz covers the surrounding user journey on this rig.

Three residual paths reloaded the OpenCode engine when the Settings
screen opened (verified live on a Daytona repro):

- cloud MCP re-mint: the one-attempt-per-unhealthy-episode guard was a
  closure variable in a store recreated on every settings mount, so a
  persistently unhealthy openwork-cloud MCP re-minted its token (runtime
  config write + reload) on every settings open. The attempt marker is
  now persisted (org-scoped) and cleared when the entry connects or the
  user forces a refresh.
- cloud provider sync could run before the OpenWork server target
  resolved; the baseline read then fell back to an empty source and
  re-imported every org provider (auth PUT + config PATCH + dispose
  churn). The pass now requires the resolved target up front - imports
  and persistence need it anyway.
- selecting the already-active workspace in the settings workspace menu
  POSTed /workspaces/:id/activate, which reloaded the engine
  unconditionally. Same-id selections now return early in the app, and
  the server skips the reload when the workspace is already active
  (switch reloads stay, #870).
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment Jul 7, 2026 4:59pm
openwork-den Ready Ready Preview, Comment Jul 7, 2026 4:59pm
openwork-den-worker-proxy Ready Ready Preview, Comment Jul 7, 2026 4:59pm
openwork-landing Ready Ready Preview, Comment, Open in v0 Jul 7, 2026 4:59pm

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.

1 participant