Tencent/WeKnora · error

release stale sandbox binding: %w

Error message

release stale sandbox binding: %w

What it means

When a binding is stale (its sandbox boots an image the config has since replaced) and a rebuild is permitted at this turn boundary, resolveLocked destroys the old sandbox via destroyBindingLocked before the recovery pass re-creates/adopts one. This error wraps a failure of that destroy (provider Destroy API error, binding store error, or context cancellation). Destroying before rebuilding is required — a surviving stale sandbox would simply be re-adopted — so the lifecycle refuses to continue on failure.

Source

Thrown at internal/sandbox/session_lifecycle.go:192

		if !deleted {
			return nil, errors.New("mismatched provider binding changed during replacement")
		}
		binding = nil
	}

	// A stale binding is one whose sandbox boots an image the config has since
	// replaced. Rebuild waits for a turn boundary: the first resolve of a new
	// chat turn may destroy and recreate, later resolves of that same turn
	// keep the sandbox so /workspace scratch and in-flight execs survive an
	// install that landed mid-turn. A resolve with no turn lease (no AgentQA
	// in flight) still rebuilds immediately.
	//
	// Destroying before rebuilding is not optional: the recovery pass below
	// adopts any live sandbox carrying this session's metadata, so a surviving
	// one would simply be picked up again.
	if binding != nil && binding.StaleAt != nil && l.shouldRebuildStaleBinding(ctx, key) {
		if err := l.destroyBindingLocked(ctx, key, *binding); err != nil {
			return nil, fmt.Errorf("release stale sandbox binding: %w", err)
		}
		binding = nil
	}
	// First resolve of a turn spends rebuildOnce even when nothing was stale,
	// so a later install in the same turn cannot tear the sandbox down.
	l.consumeTurnRebuild(ctx, key)

	if binding != nil {
		handle, replace, err := l.connectBinding(ctx, *binding)
		if err != nil {
			return nil, err
		}
		if !replace {
			return handle, nil
		}
		deleted, err := l.bindings.DeleteIfMatch(
			ctx,
			key,

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Retry Resolve with backoff — the rebuild will be re-attempted at the next eligible resolve.
  2. Check the provider destroy error in the %w chain; verify the cleanupTimeout is generous enough for the provider's delete latency.
  3. If the provider API is degraded, wait for recovery; the old stale sandbox may keep running (and billing) until destroy succeeds — check the provider console for orphans.
  4. Avoid cancelling requests during turn-start resolves so rebuilds complete.

Example fix

// before
cleanupTimeout := 5 * time.Second // too short for provider deletes
// after
cleanupTimeout := 60 * time.Second // tolerate provider delete latency during stale rebuild
// plus retry on resolve:
for i := 0; i < 3; i++ {
    handle, err = lifecycle.Resolve(ctx, key)
    if err == nil || errors.Is(err, sandbox.ErrSandboxSessionDeleted) { break }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

open, canRebuild, err := store.TurnState(ctx, key)
if err == nil && !canRebuild {
    // stale rebuild will be deferred to next turn boundary; no destroy imminent
}

Try / catch

handle, err := lifecycle.Resolve(ctx, key)
if err != nil && strings.Contains(err.Error(), "release stale sandbox binding") {
    // provider destroy failed during rebuild; retry next turn boundary
    time.Sleep(backoff)
    handle, err = lifecycle.Resolve(ctx, key)
}

Prevention

When it happens

Trigger: A sandbox config/template change marked existing bindings stale; the first resolve of a new turn (or a resolve with no turn lease) triggers shouldRebuildStaleBinding; the destroyBindingLocked call fails because the provider API errors or the context is cancelled mid-destroy.

Common situations: Rotating the sandbox image/template while sessions are live; provider API outage or rate limiting exactly at rebuild time; cleanupTimeout too short so the provider destroy times out; user cancels the request mid-rebuild.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/901406a10c2cf65f. Report an issue: GitHub.