Tencent/WeKnora · error
resolve remote sandbox for session: %w
Error message
resolve remote sandbox for session: %w
What it means
Resolve wraps any failure inside the per-session lifecycle lock — binding reads, session existence checks, provider-mismatch cleanup, stale rebuilds, connect, recovery, or create — with this error. The sandbox for the session could not be resolved, so no handle is returned. Callers (including several tests) rely on the wrapped cause to distinguish deleted sessions (ErrSandboxSessionDeleted), transient provider errors, and lock timeouts.
Source
Thrown at internal/sandbox/session_lifecycle.go:114
func (l *remoteSessionLifecycle) Resolve(
ctx context.Context,
key SessionSandboxKey,
) (RemoteSandboxHandle, error) {
if err := key.Validate(); err != nil {
return nil, err
}
var handle RemoteSandboxHandle
err := l.bindings.WithLifecycleLock(ctx, key, func(lockCtx context.Context) error {
resolved, err := l.resolveLocked(lockCtx, key)
if err != nil {
return err
}
handle = resolved
return nil
})
if err != nil {
return nil, fmt.Errorf("resolve remote sandbox for session: %w", err)
}
if handle == nil {
return nil, errors.New("resolve remote sandbox returned no handle")
}
return handle, nil
}
// Destroy removes the bound remote sandbox and then compare-deletes its
// binding. It is idempotent for absent and already-deleted sandboxes.
func (l *remoteSessionLifecycle) Destroy(
ctx context.Context,
key SessionSandboxKey,
) error {
if err := key.Validate(); err != nil {
return err
}
err := l.bindings.WithLifecycleLock(ctx, key, func(lockCtx context.Context) error {
binding, err := l.readBinding(lockCtx, key)View on GitHub (pinned to 988cbb0330)
Solutions
- Unwrap the chain with errors.Is/As: check for ErrSandboxSessionDeleted (do not retry — the session is gone) versus transient provider/Redis errors (retry with backoff).
- Verify the session key (tenant/session IDs) is correct and the session still exists in the durable store.
- Check remote provider API health/quotas if the wrapped cause is a create/connect failure.
- If it is a lock timeout, reduce lock contention or inspect for leaked lifecycle locks in the binding store.
Example fix
// before
handle, err := lifecycle.Resolve(ctx, key)
if err != nil {
return err
}
// after
handle, err := lifecycle.Resolve(ctx, key)
if err != nil {
if errors.Is(err, sandbox.ErrSandboxSessionDeleted) {
return nil // session ended; nothing to resolve
}
return fmt.Errorf("resolve sandbox: %w", err) // retryable path
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := key.Validate(); err != nil {
return fmt.Errorf("invalid session key before resolve: %w", err)
}
exists, err := checker.SessionExists(ctx, key)
if err == nil && !exists {
return nil // skip resolve; session already gone
} Type guard
func isSessionDeletedErr(err error) bool {
return errors.Is(err, sandbox.ErrSandboxSessionDeleted)
} Try / catch
handle, err := lifecycle.Resolve(ctx, key)
switch {
case err == nil:
// use handle
case errors.Is(err, sandbox.ErrSandboxSessionDeleted):
return nil // expected teardown path
default:
return fmt.Errorf("resolve remote sandbox for session: %w", err) // retry/backoff
} Prevention
- Always special-case ErrSandboxSessionDeleted before generic retries.
- Give Resolve a context budget covering lock wait plus provider calls.
- Monitor provider API error rates feeding Resolve.
- Avoid resolving sandboxes for sessions you just deleted.
When it happens
Trigger: remoteSessionLifecycle.Resolve is called for a session key and the inner resolveLocked fails: WithLifecycleLock times out or errors, the owning session is gone, the provider create/connect call fails, or a binding compare-delete races and loses.
Common situations: Chat turn starts while another node holds the lifecycle lock; the owning chat session was deleted concurrently (returns ErrSandboxSessionDeleted wrapped here); the remote provider API is down or rate-limiting; Redis binding-store errors during compare-delete.
Related errors
- sandbox: no live sandbox for session %s
- sandbox session no longer exists
- sandbox: %s backend must be constructed via NewSessionBoundM
- destroy remote sandbox for session: %w
- sandbox: config is missing required fields
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/a69bed0ea54b8076.
Report an issue: GitHub.