Tencent/WeKnora · error
delete mismatched provider binding: %w
Error message
delete mismatched provider binding: %w
What it means
When resolveLocked finds a binding whose Provider differs from the current client's provider, it deletes the stale binding using the compare-and-delete DeleteIfMatch so only the exact old binding is removed. This error wraps a failure of that DeleteIfMatch call (Redis error). It exists to guarantee provider replacement is atomic: if the binding changed concurrently, a separate "changed during replacement" error is returned instead.
Source
Thrown at internal/sandbox/session_lifecycle.go:172
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)
}
if !deleted {
return nil, errors.New("mismatched provider binding changed during replacement")
}
binding = nil
}
// A stale binding is one whose sandbox boots an image the config has since
// replaced. Rebuild waits for a turn boundary: the first resolve of a new
// chat turn may destroy and recreate, later resolves of that same turn
// keep the sandbox so /workspace scratch and in-flight execs survive an
// install that landed mid-turn. A resolve with no turn lease (no AgentQA
// in flight) still rebuilds immediately.
//
// Destroying before rebuilding is not optional: the recovery pass below
// adopts any live sandbox carrying this session's metadata, so a surviving
// one would simply be picked up again.
if binding != nil && binding.StaleAt != nil && l.shouldRebuildStaleBinding(ctx, key) {View on GitHub (pinned to 988cbb0330)
Solutions
- Fix Redis connectivity if the wrapped cause is a store error, then retry Resolve.
- If switching providers intentionally, complete the migration during low traffic and retry resolves so mismatched bindings drain.
- Verify the binding store replication/cluster is healthy so compare-and-delete ops succeed consistently.
- After retries fail, inspect the binding row manually and clear the stale binding to unblock resolution.
Example fix
// before
// provider switched in config, resolve fails
handle, err := lifecycle.Resolve(ctx, key)
// after
handle, err := lifecycle.Resolve(ctx, key)
if err != nil {
var netErr *net.OpError
if errors.As(err, &netErr) { // Redis connectivity during mismatch cleanup
time.Sleep(backoff)
handle, err = lifecycle.Resolve(ctx, key)
}
} Defensive patterns
Strategy: retry
Validate before calling
// confirm provider switch is intentional and old bindings exist only for the old provider
old, err := store.GetBinding(ctx, key)
if err == nil && old != nil && old.Provider == currentProvider {
// no mismatch path will run
} Try / catch
handle, err := lifecycle.Resolve(ctx, key)
if err != nil && strings.Contains(err.Error(), "delete mismatched provider binding") {
if isRetryable(err) {
time.Sleep(backoff)
handle, err = lifecycle.Resolve(ctx, key)
}
} Prevention
- Perform provider migrations during quiet windows and drain old bindings before cutover.
- Keep the binding Redis cluster healthy (replication, failover drills).
- Log binding provider changes to spot migration churn.
- Retry resolves rather than manually editing bindings except as a last resort.
When it happens
Trigger: A session was previously bound to provider A (e.g. after a provider migration or config change) and is now resolved via provider B; the DeleteIfMatch on the old binding's (provider, sandboxID) fails due to a Redis/connection error.
Common situations: Switching sandbox providers in config while old sessions still hold bindings from the previous provider, during a Redis outage or failover; partially completed provider migrations.
Related errors
- delete terminal sandbox binding: %w
- WEKNORA_REDIS_NAMESPACE must not contain braces
- WEKNORA_REDIS_NAMESPACE must not contain control characters
- failed to get FAQ import progress from Redis: %w
- failed to unmarshal FAQ import progress: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/0be318149df214c4.
Report an issue: GitHub.