Tencent/WeKnora · error
get sandbox binding: %w
Error message
get sandbox binding: %w
What it means
Get fetches the raw binding JSON from Redis by the binding key. A miss (redis.Nil) returns (nil, nil) by design, but any other Redis error — connection failure, timeout, cluster redirect, auth — is wrapped as "get sandbox binding: %w". The caller cannot distinguish store outages from other faults except through the wrapped cause.
Source
Thrown at internal/sandbox/session_binding_redis.go:122
lockLease: redisLifecycleLockLease,
lockRenewInterval: redisLifecycleLockRenewInterval,
}, nil
}
// Get returns the current binding, or nil when the session is unbound.
func (s *RedisSessionSandboxBindingStore) Get(
ctx context.Context,
key SessionSandboxKey,
) (*SessionSandboxBinding, error) {
if err := key.Validate(); err != nil {
return nil, err
}
raw, err := s.client.Get(ctx, s.bindingKey(key)).Bytes()
if errors.Is(err, redis.Nil) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("get sandbox binding: %w", err)
}
var binding SessionSandboxBinding
if err := json.Unmarshal(raw, &binding); err != nil {
return nil, fmt.Errorf("decode sandbox binding: %w", err)
}
if err := binding.Validate(key); err != nil {
return nil, fmt.Errorf("validate sandbox binding: %w", err)
}
return &binding, nil
}
// Create stores a validated current-schema binding with SET NX and no
// expiration.
func (s *RedisSessionSandboxBindingStore) Create(
ctx context.Context,
key SessionSandboxKey,
binding SessionSandboxBinding,View on GitHub (pinned to 988cbb0330)
Solutions
- Inspect the wrapped cause; fix connectivity, credentials, or cluster routing as indicated
- Retry Get with short backoff for transient Redis failures (timeouts, pool exhaustion)
- Confirm REDIS_URL/TLS/auth env configuration matches the deployed Redis topology
- For misses, remember redis.Nil returns (nil, nil) — treat that as 'no binding', not this error
Example fix
// before
b, err := store.Get(ctx, key)
if err != nil { return err }
// after
b, err := store.Get(ctx, key)
if err != nil {
if isRedisTransient(err) { return retryGet(ctx, key) }
return fmt.Errorf("binding lookup: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
if err := redisClient.Ping(ctx).Err(); err != nil {
return fmt.Errorf("redis unreachable: %w", err)
} Type guard
func bindingExists(b *sandbox.SessionSandboxBinding, err error) bool {
return err == nil && b != nil // (nil, nil) means miss, not error
} Try / catch
b, err := store.Get(ctx, key)
if err != nil {
if isRedisTransient(err) { return retryGet(ctx, key) }
return fmt.Errorf("binding get: %w", err)
}
if b == nil { return errNoBinding } // redis.Nil miss path Prevention
- Distinguish the (nil, nil) miss from errors in callers
- Retry transient Redis errors with backoff
- Monitor Redis health and pool saturation
- Validate REDIS_URL/TLS/auth config in deploy checks
When it happens
Trigger: Calling Get while Redis is unreachable, the client's dial/auth settings are wrong, a read timeout elapses, or MOVED/CLUSTER errors occur in clustered deployments.
Common situations: Redis restart or failover mid-session; wrong REDIS_URL/password in the environment; connection pool exhausted under load; network partition between app and Redis.
Related errors
- create sandbox binding: %w
- delete sandbox binding: %w
- scan sandbox bindings: %w
- WEKNORA_REDIS_NAMESPACE must not contain braces
- WEKNORA_REDIS_NAMESPACE must not contain control characters
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/e2993a9c3f52156a.
Report an issue: GitHub.