Tencent/WeKnora · warning
mark session %s stale: %w
Error message
mark session %s stale: %w
What it means
InvalidateByConfig marks every binding for a config stale in parallel; the per-session markBindingStale work runs under an acquire timer. If marking one session fails, the error is collected (not returned immediately) as "mark session <id> stale: %w" and joined with other failures via errors.Join. InvalidateByConfig ultimately surfaces the joined error to its caller.
Source
Thrown at internal/sandbox/session_binding.go:232
}
if binding.ConfigID != wanted || binding.StaleAt != nil {
return nil
}
wrote, err := store.markBindingStale(
markCtx, key, *binding, time.Now().UTC(),
)
if err != nil {
return err
}
if wrote {
marked++
}
return nil
})
acquireTimer.Stop()
cancel()
if err != nil {
failures = append(failures, fmt.Errorf("mark session %s stale: %w", key.SessionID, err))
}
}
return marked, errors.Join(failures...)
}
type lifecycleOwnershipContextKey struct{}
func withLifecycleOwnershipContext(
ctx context.Context,
ownershipCtx context.Context,
) context.Context {
return context.WithValue(ctx, lifecycleOwnershipContextKey{}, ownershipCtx)
}
func lifecycleOwnershipContext(ctx context.Context) context.Context {
if ownershipCtx, ok := ctx.Value(lifecycleOwnershipContextKey{}).(context.Context); ok {
return ownershipCtx
}View on GitHub (pinned to 988cbb0330)
Solutions
- Inspect the joined error to find which session IDs failed and retry InvalidateByConfig or targeted marks for those
- Increase the acquire/lifecycle-lock timeout or reduce concurrency of invalidation sweeps
- Check Redis health/latency; the failures are usually store-side contention or timeouts
- Verify no other process holds the lifecycle lock on the affected sessions
Example fix
// before
if err := store.InvalidateByConfig(ctx, tenant, cfg); err != nil {
log.Fatal(err) // opaque joined error
}
// after
if err := store.InvalidateByConfig(ctx, tenant, cfg); err != nil {
for _, part := range strings.Split(err.Error(), "\n") {
log.Warnf("partial invalidate: %s", part) // retry per failed session
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := store.Ping(ctx); err != nil {
return fmt.Errorf("postpone invalidation: store degraded: %w", err)
} Try / catch
if err := store.InvalidateByConfig(ctx, tenant, cfg); err != nil {
for _, failure := range strings.Split(err.Error(), "\n") {
if id, ok := parseFailedSession(failure); ok {
retryMarkStale(ctx, tenant, cfg, id)
}
}
} Prevention
- Retry failed per-session marks individually after a sweep
- Spread large invalidations to reduce lock contention
- Monitor Redis latency; raise acquire budgets under load
When it happens
Trigger: Invalidating bindings by config while the store is degraded: Redis timeouts exceeding the acquire deadline, connection pool exhaustion, or a single key being locked by another worker's lifecycle lock.
Common situations: Redis under load during incident-driven mass invalidation; lock contention between concurrent reapers and invalidators; partial network failures hitting only some sessions.
Related errors
- sandbox: docker client requires a config
- sandbox: docker backend requires an image
- daemon returned no container state
- e2b remote client config is required
- E2BAPIKey is required for the E2B backend
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/b85a94b3726c4718.
Report an issue: GitHub.