Tencent/WeKnora · error
sandbox: list workspace %d config %q sandboxes: %w
Error message
sandbox: list workspace %d config %q sandboxes: %w
What it means
The reaper lists sandboxes matching the tenant/config filter via deps.Client.List; when the underlying store call fails, the error is wrapped with the workspace ID and normalized config ID so the failed scope is identifiable. This is a wrapped storage/backend error, not raised by the sandbox package logic itself.
Source
Thrown at internal/sandbox/orphan_reaper.go:69
Grace time.Duration
Now func() time.Time
}
// ReapOrphanSandboxes deletes unbound sandboxes for one tenant and reports how
// many were removed.
func ReapOrphanSandboxes(ctx context.Context, deps OrphanReaperDeps) (int, error) {
if deps.Client == nil {
return 0, fmt.Errorf("sandbox: orphan reaper requires a client")
}
now := deps.Now
if now == nil {
now = time.Now
}
summaries, err := deps.Client.List(ctx, configSandboxFilter(deps.TenantID, deps.ConfigID))
if err != nil {
return 0, fmt.Errorf(
"sandbox: list workspace %d config %q sandboxes: %w",
deps.TenantID, NormalizeConfigID(deps.ConfigID), err)
}
cutoff := now().Add(-deps.Grace)
deleted := 0
for _, summary := range summaries {
if _, bound := deps.BoundIDs[summary.ID]; bound {
continue
}
if deps.Grace > 0 && !summary.StartedAt.IsZero() && summary.StartedAt.After(cutoff) {
continue
}
if err := deps.Client.Delete(ctx, summary.ID); err != nil {
// Keep going: one undeletable sandbox must not abort the sweep.
continue
}
deleted++View on GitHub (pinned to 988cbb0330)
Solutions
- Inspect the wrapped cause (%w) for the actual transport/auth failure and fix connectivity or credentials
- Retry the reap with backoff, since List failures are often transient
- Verify TenantID/ConfigID passed to the reaper match an existing workspace config
- Log the wrapped error with the workspace/config scope before alerting
Example fix
// before
_, err := sandbox.ReapOrphanSandboxes(ctx, deps) // err surfaces opaque store failure
// after
n, err := sandbox.ReapOrphanSandboxes(ctx, deps)
if err != nil {
var nerr net.Error
if errors.As(err, &nerr) { scheduleRetry(ctx, deps); return }
log.Fatalf("reap failed for workspace %d: %v", deps.TenantID, err)
} Defensive patterns
Strategy: retry
Validate before calling
if err := client.Ping(ctx); err != nil {
return fmt.Errorf("sandbox store unreachable: %w", err)
} Try / catch
n, err := sandbox.ReapOrphanSandboxes(ctx, deps)
if err != nil {
var nerr net.Error
if errors.As(err, &nerr) { return scheduleRetry(deps) }
return err
} Prevention
- Ping the store before scheduled reaps
- Retry List-dependent operations with exponential backoff
- Alert on repeated reap failures with workspace scope included
When it happens
Trigger: ReapOrphanSandboxes invoked with a Client whose List call returns an error — e.g. Redis down, network timeout, auth rejected, or malformed filter arguments like an invalid config ID.
Common situations: Store outage during a scheduled reap; wrong Redis address or credentials in the reaper's environment; deleted config whose ID no longer resolves server-side; transient network partitions in CI.
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/ec7e89699a1af123.
Report an issue: GitHub.