Tencent/WeKnora · error
create sandbox binding: %w
Error message
create sandbox binding: %w
What it means
This error wraps a failure from bindings.Create when persisting the binding for a newly created sandbox. The sandbox was created successfully, but without a durable binding the session could not be re-resolved later, so the lifecycle cleans up the fresh sandbox (cleanupCreated) and returns 'create sandbox binding: %w' joined with any cleanup error via errors.Join.
Source
Thrown at internal/sandbox/session_lifecycle.go:387
return nil, errors.Join(
fmt.Errorf("recheck owning session: %w", checkErr),
l.cleanupCreated(ctx, handle),
)
}
if !exists {
return nil, errors.Join(ErrSandboxSessionDeleted, l.cleanupCreated(ctx, handle))
}
binding := l.newBinding(
key,
handle.ID(),
request.TemplateID,
l.now().UTC(),
)
created, bindErr := l.bindings.Create(ctx, key, binding)
if bindErr != nil {
return nil, errors.Join(
fmt.Errorf("create sandbox binding: %w", bindErr),
l.cleanupCreated(ctx, handle),
)
}
if created {
return handle, nil
}
winner, winnerErr := l.readBinding(ctx, key)
if winnerErr != nil {
// The authoritative winner is unknown, so deleting this sandbox could
// destroy the resource another coordinator just bound.
return nil, fmt.Errorf("read winning sandbox binding: %w", winnerErr)
}
if winner != nil &&
winner.Provider == l.client.Provider() &&
winner.SandboxID == handle.ID() {
return handle, nil
}View on GitHub (pinned to 988cbb0330)
Solutions
- Inspect the wrapped (joined) error for binding-store detail; note the created sandbox is cleaned up automatically so retrying is safe
- Retry the resolve operation — a fresh sandbox will be created and bound
- Check for concurrent resolvers of the same session key and add client-side locking/idempotency if your store lacks it
- Verify write permissions and record size limits on the binding backend
Example fix
// before // two goroutines resolve the same key concurrently // after cmu.Lock() // serialize resolution per session key in the host process handle, err := session.Resolve(ctx, key) mu.Unlock()
Defensive patterns
Strategy: retry
Validate before calling
// check binding-store writability before creating sandboxes
if err := bindings.HealthCheck(ctx); err != nil {
return fmt.Errorf("skip create; binding store down: %w", err)
} Try / catch
handle, err := session.Resolve(ctx, key)
if err != nil && errors.Is(err, context.Canceled) {
// joined cleanup error: inspect both halves
return err
} else if err != nil && strings.Contains(err.Error(), "create sandbox binding:") {
// created sandbox was cleaned up; safe to retry
err = retryWithBackoff(ctx, 3, func() error { handle, err = session.Resolve(ctx, key); return err })
} Prevention
- Serialize resolution per session key to avoid bind races
- Health-check the binding store before provisioning (saves a create+cleanup cycle)
- Keep binding records small and schema-stable
- Grant the service account unconditional write access to the binding backend
When it happens
Trigger: l.bindings.Create(ctx, key, binding) returns an error during createAndBind, immediately after a successful client.Create and session-existence recheck — binding store unavailability, write conflicts with a concurrent resolver that won the race, permission errors, or invalid binding record fields.
Common situations: Two processes resolving the same session concurrently (one binds first; store rejects or errors for the other); binding-store outage; schema migration in progress; quota/size limits on the binding record (e.g. large metadata); revoked write permissions.
Related errors
- bind owned remote sandbox: %w
- recheck owning session: %w
- create default %s page: %w
- save: %w
- failed to write file: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/19d012c130437145.
Report an issue: GitHub.