Tencent/WeKnora · error
read winning sandbox binding: %w
Error message
read winning sandbox binding: %w
What it means
During createAndBind, a coordinator lost the binding-create race (another coordinator already created a binding for this session). The code reads the winning binding to decide whether to keep or clean up its newly created sandbox. If reading the winner fails, the outcome is unknown, so the library refuses to proceed — deleting the new sandbox could destroy a resource another coordinator just bound.
Source
Thrown at internal/sandbox/session_lifecycle.go:399
request.TemplateID,
l.now().UTC(),
)
created, bindErr := l.bindings.Create(ctx, key, binding)
if bindErr != nil {
return nil, errors.Join(
fmt.Errorf("create sandbox binding: %w", bindErr),
l.cleanupCreated(ctx, handle),
)
}
if created {
return handle, nil
}
winner, winnerErr := l.readBinding(ctx, key)
if winnerErr != nil {
// The authoritative winner is unknown, so deleting this sandbox could
// destroy the resource another coordinator just bound.
return nil, fmt.Errorf("read winning sandbox binding: %w", winnerErr)
}
if winner != nil &&
winner.Provider == l.client.Provider() &&
winner.SandboxID == handle.ID() {
return handle, nil
}
if cleanupErr := l.cleanupCreated(ctx, handle); cleanupErr != nil {
return nil, fmt.Errorf("cleanup losing remote sandbox: %w", cleanupErr)
}
if winner == nil {
return nil, errors.New("sandbox binding create lost without a winner")
}
return l.connectKnownWinner(ctx, *winner)
}
func (l *remoteSessionLifecycle) connectWinner(
ctx context.Context,
key SessionSandboxKey,View on GitHub (pinned to 988cbb0330)
Solutions
- Check connectivity/health of the SessionSandboxBindingStore and resolve the wrapped underlying error
- Retry the session resolve operation — the failure is often transient and the winner will be readable on retry
- Verify store authentication/permissions allow Get on the binding key
- Inspect the wrapped error (%w chain) for store-specific causes like timeouts or auth failures
Example fix
// before
handle, err := manager.Resolve(ctx, sessionKey)
// after
handle, err := manager.Resolve(ctx, sessionKey)
if err != nil && strings.Contains(err.Error(), "read winning sandbox binding") {
// transient store read failure during race resolution — retry
handle, err = manager.Resolve(ctx, sessionKey)
} Defensive patterns
Strategy: retry
Validate before calling
// Probe binding-store availability before resolving
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if _, err := store.Get(ctx, key); err != nil {
// store unreachable; skip resolve until it recovers
} Try / catch
handle, err := manager.Resolve(ctx, key)
if err != nil && strings.Contains(err.Error(), "read winning sandbox binding") {
// transient store read during race resolution
time.Sleep(50*time.Millisecond)
handle, err = manager.Resolve(ctx, key)
} Prevention
- Deploy a health check on the binding store before admitting session traffic
- Use short bounded retries around session resolve for store blips
- Monitor store read latency; alert before it exceeds request budgets
When it happens
Trigger: Two coordinators concurrently allocate a sandbox for the same session key; this instance's bindings.Create loses the race, and the follow-up readBinding call to the binding store fails (store outage, timeout, transient network error).
Common situations: Binding-store (e.g. Redis/etcd/DB) connectivity blips or timeouts under load; multiple manager instances scaling horizontally; context cancellation during the read.
Related errors
- get sandbox binding: %w
- delete sandbox binding: %w
- validate sandbox binding: %w
- model ID cannot be empty
- model is currently downloading
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/0eaa1de5221ce070.
Report an issue: GitHub.