Skip to content

Commit 081485c

Browse files
icecrasher321claude
andcommitted
fix(sandboxes): let a same-spec save retry a failed build
Cursor Bugbot. `scheduleSandboxBuild` sat inside the changed-hash branch, so a save that did not alter the package list never reached the registry. The comment above it described the opposite — that an unchanged spec finds a ready row and enqueues nothing — which is what `ensureSandboxImage` does, but only if it is called. That made the docs wrong too. They tell a reader to save the sandbox again to retry a failed build immediately, and this branch is exactly why that did nothing: the only way to retry was to edit the package list into a different hash, which is not what someone recovering from a transient registry failure wants to do. The call is now unconditional and the registry decides what a save costs, which is what its conflict guard is for: a ready or in-flight row is left alone, a failed one is re-claimed at once. Releasing the previous image stays behind the hash check, since only a changed hash orphans one. Cache invalidation is unchanged — `scheduleSandboxBuild` already does it, which is why the else branch existed. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent e446f2b commit 081485c

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

  • apps/sim/app/api/workspaces/[id]/sandboxes/[sandboxId]

apps/sim/app/api/workspaces/[id]/sandboxes/[sandboxId]/route.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,19 @@ export const PATCH = withRouteHandler(async (request: NextRequest, context: Sand
8686
throw error
8787
}
8888

89-
// An unchanged spec re-points at the same content address, so `ensureSandboxImage`
90-
// finds a `ready` row and enqueues nothing. Editing the name alone costs no build.
89+
// Unconditional, because the registry decides what a save costs: a `ready` or
90+
// in-flight row is left alone, so renaming or re-saving an unchanged spec
91+
// enqueues nothing, while a failed one gets the immediate retry a person saving
92+
// is asking for. Gating this on a changed hash meant a same-spec save silently
93+
// did nothing, and the only way to retry a failed build was to edit the package
94+
// list into a different hash.
95+
await scheduleSandboxBuild(spec)
96+
9197
if (spec.specHash !== existing.specHash) {
92-
await scheduleSandboxBuild(spec)
9398
// The previous content address is unreferenced by this sandbox now. Release
9499
// no-ops when another sandbox still declares the same package list.
95100
runDetached('release-sandbox-image', () => releaseSandboxImage(existing.specHash))
96101
logger.info('Sandbox spec changed, scheduled a build', { workspaceId, sandboxId })
97-
} else {
98-
invalidateSandboxResolution()
99102
}
100103

101104
const sandbox = await readWorkspaceSandbox(workspaceId, sandboxId)

0 commit comments

Comments
 (0)