Tencent/WeKnora · error
check owning session: %w
Error message
check owning session: %w
What it means
resolveLocked checks the durable session record via SessionExistenceChecker before touching sandboxes. This error wraps a failure of that check itself (as opposed to the session merely not existing, which yields ErrSandboxSessionDeleted). The lifecycle throws it because it cannot safely decide whether to keep or destroy the sandbox without knowing whether the owning session exists.
Source
Thrown at internal/sandbox/session_lifecycle.go:155
})
if err != nil {
return fmt.Errorf("destroy remote sandbox for session: %w", err)
}
return nil
}
func (l *remoteSessionLifecycle) resolveLocked(
ctx context.Context,
key SessionSandboxKey,
) (RemoteSandboxHandle, error) {
binding, err := l.readBinding(ctx, key)
if err != nil {
return nil, err
}
exists, err := l.sessionChecker.SessionExists(ctx, key)
if err != nil {
return nil, fmt.Errorf("check owning session: %w", err)
}
if !exists {
if binding != nil {
err = l.destroyBindingLocked(ctx, key, *binding)
}
return nil, errors.Join(ErrSandboxSessionDeleted, err)
}
if binding != nil && binding.Provider != l.client.Provider() {
deleted, err := l.bindings.DeleteIfMatch(
ctx,
key,
binding.Provider,
binding.SandboxID,
)
if err != nil {
return nil, fmt.Errorf("delete mismatched provider binding: %w", err)
}View on GitHub (pinned to 988cbb0330)
Solutions
- Check the session existence store's connectivity/config (DSN, credentials, pool limits) and fix the underlying error from the %w chain.
- Increase the context deadline for Resolve so the existence check is not starved after lock acquisition.
- Retry Resolve with backoff — the check is read-only and safe to re-issue.
- Add health checks/alerting on the session store so outages are caught before sandbox resolution.
Example fix
// before
ctx := context.WithTimeout(context.Background(), 3*time.Second)
handle, err := lifecycle.Resolve(ctx, key)
// after
ctx := context.WithTimeout(context.Background(), 15*time.Second) // allow for lock wait + session check
handle, err := lifecycle.Resolve(ctx, key)
if err != nil && !errors.Is(err, sandbox.ErrSandboxSessionDeleted) {
// inspect errors.Unwrap chain for session-store connectivity issues
} Defensive patterns
Strategy: retry
Validate before calling
if err := rdb.Ping(ctx).Err(); err != nil {
return fmt.Errorf("session store down before resolve: %w", err)
} Try / catch
exists, err := checker.SessionExists(ctx, key)
if err != nil {
if isRetryable(err) {
time.Sleep(backoff)
exists, err = checker.SessionExists(ctx, key)
}
if err != nil { return fmt.Errorf("session store unavailable: %w", err) }
} Prevention
- Health-check the session store before processing turns.
- Size DB/Redis connection pools for lock-holding resolve paths.
- Give Resolve a deadline that leaves room after lock acquisition.
- Alert on session-store error rates, since every sandbox resolve depends on it.
When it happens
Trigger: resolveLocked calls sessionChecker.SessionExists and the checker's backing store (e.g. the session database/Redis) errors — connection failure, timeout, or context cancellation during the existence query.
Common situations: Session store database outage or connection pool exhaustion; misconfigured session store DSN; context deadline exceeded because the lifecycle lock wait already consumed most of the deadline; permission errors on the session table.
Related errors
- sandbox: config is missing required fields
- cube remote client config is required
- cube api: create sandbox: empty sandboxID
- sandbox: docker backend is disabled; enable it in System Set
- sandbox: docker client requires a config
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/183e87a09d79c0a2.
Report an issue: GitHub.