Skip to content

fix(sandbox): reconcile stale VIRTUAL_MCP cache so preview unsticks w…#4041

Open
Rooseveltfj wants to merge 1 commit into
decocms:mainfrom
Rooseveltfj:fix/3482-sandbox-stale-cache
Open

fix(sandbox): reconcile stale VIRTUAL_MCP cache so preview unsticks w…#4041
Rooseveltfj wants to merge 1 commit into
decocms:mainfrom
Rooseveltfj:fix/3482-sandbox-stale-cache

Conversation

@Rooseveltfj

@Rooseveltfj Rooseveltfj commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Problem

When the sandboxMap entry is written by a path that doesn't resolve a client-side useSandboxStart mutation — agent-triggered start, another tab, or an SSE reconnect onto an already-running pod — the cached VIRTUAL_MCP entity stays stale. previewUrl resolves to null even though the dev server reports running, so the preview sticks on "Server is starting…" and the Sections Editor stays inaccessible until a hard refresh re-fetches the entity. This matches the issue's "requires refresh on first open."

Root cause

previewUrl is derived only from the React-Query-cached entity (COLLECTION_VIRTUAL_MCP_GET, staleTime 60s, no polling). The SSE stream carries phase but never previewUrl, and no cache invalidation is tied to the SSE lifecycle. So any write path that doesn't go through the mutation's onSuccess leaves the cache stale for up to 60s — exactly the window where a hard refresh "fixes" it.

(Slightly narrower than the trigger described in the issue: the stuck state is reproducible whenever the cache is stale with phase === 'running', not only on first CMS-tab open.)

Fix

Adds a stale-cache reconcile in SandboxLifecycleProvider: when the pod reports running but the cache still has no previewUrl, invalidate the VIRTUAL_MCP query once so previewUrl re-resolves. Gated on:

  • phase === 'running' — write is guaranteed landed, avoids re-fetching before the row exists (no early-write race)
  • !previewUrl — warm path untouched, zero regression
  • deduped per sandbox arrival via a kind-aware key, mirroring the existing shouldAutoStart / shouldSelfHeal effects in the same file

Reuses invalidateVirtualMcpQueries. Touches only VIRTUAL_MCP keys, so no redundant refetch of decofile / liveMeta.

Interaction with #4034

Consistent. decofile / meta are gated on devServerReady and resolve via the mesh proxy, independent of previewUrl, so they're unaffected. This fix restores the previewUrl that gives the iframe its local src — enabling (not conflicting with) #4034's browser-reachable fetch path.

Verification

Fixes #3482


Summary by cubic

Unsticks the sandbox preview by reconciling a stale VIRTUAL_MCP cache when the dev server is already running, removing the need to refresh. Fixes #3482.

  • Bug Fixes
    • In SandboxLifecycleProvider, when SSE reports phase === 'running' but cached previewUrl is null, invalidate VIRTUAL_MCP queries once (keyed by vmId:branch:kind) to re-fetch and populate the preview URL.
    • Deduped per arrival and skipped when previewUrl exists, not running, or user stopped; dedup resets once the preview is available or on restart. Only VIRTUAL_MCP queries are touched (no decofile/liveMeta refetch).
    • Added unit tests for shouldReconcileStaleCache.

Written for commit 81cd1a3. Summary will update on new commits.

Review in cubic

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.

Sections-editor tab requires page refresh on first open (sandboxMap race)

1 participant