{"record":{"id":"0eaa1de5221ce070","repo":"Tencent/WeKnora","slug":"read-winning-sandbox-binding-w","errorCode":null,"errorMessage":"read winning sandbox binding: %w","messagePattern":"read winning sandbox binding: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_lifecycle.go","lineNumber":399,"sourceCode":"\t\trequest.TemplateID,\n\t\tl.now().UTC(),\n\t)\n\tcreated, bindErr := l.bindings.Create(ctx, key, binding)\n\tif bindErr != nil {\n\t\treturn nil, errors.Join(\n\t\t\tfmt.Errorf(\"create sandbox binding: %w\", bindErr),\n\t\t\tl.cleanupCreated(ctx, handle),\n\t\t)\n\t}\n\tif created {\n\t\treturn handle, nil\n\t}\n\n\twinner, winnerErr := l.readBinding(ctx, key)\n\tif winnerErr != nil {\n\t\t// The authoritative winner is unknown, so deleting this sandbox could\n\t\t// destroy the resource another coordinator just bound.\n\t\treturn nil, fmt.Errorf(\"read winning sandbox binding: %w\", winnerErr)\n\t}\n\tif winner != nil &&\n\t\twinner.Provider == l.client.Provider() &&\n\t\twinner.SandboxID == handle.ID() {\n\t\treturn handle, nil\n\t}\n\tif cleanupErr := l.cleanupCreated(ctx, handle); cleanupErr != nil {\n\t\treturn nil, fmt.Errorf(\"cleanup losing remote sandbox: %w\", cleanupErr)\n\t}\n\tif winner == nil {\n\t\treturn nil, errors.New(\"sandbox binding create lost without a winner\")\n\t}\n\treturn l.connectKnownWinner(ctx, *winner)\n}\n\nfunc (l *remoteSessionLifecycle) connectWinner(\n\tctx context.Context,\n\tkey SessionSandboxKey,","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_lifecycle.go#L381-L417","documentation":"During createAndBind, a coordinator lost the binding-create race (another coordinator already created a binding for this session). The code reads the winning binding to decide whether to keep or clean up its newly created sandbox. If reading the winner fails, the outcome is unknown, so the library refuses to proceed — deleting the new sandbox could destroy a resource another coordinator just bound.","triggerScenarios":"Two coordinators concurrently allocate a sandbox for the same session key; this instance's bindings.Create loses the race, and the follow-up readBinding call to the binding store fails (store outage, timeout, transient network error).","commonSituations":"Binding-store (e.g. Redis/etcd/DB) connectivity blips or timeouts under load; multiple manager instances scaling horizontally; context cancellation during the read.","solutions":["Check connectivity/health of the SessionSandboxBindingStore and resolve the wrapped underlying error","Retry the session resolve operation — the failure is often transient and the winner will be readable on retry","Verify store authentication/permissions allow Get on the binding key","Inspect the wrapped error (%w chain) for store-specific causes like timeouts or auth failures"],"exampleFix":"// before\nhandle, err := manager.Resolve(ctx, sessionKey)\n// after\nhandle, err := manager.Resolve(ctx, sessionKey)\nif err != nil && strings.Contains(err.Error(), \"read winning sandbox binding\") {\n    // transient store read failure during race resolution — retry\n    handle, err = manager.Resolve(ctx, sessionKey)\n}","handlingStrategy":"retry","validationCode":"// Probe binding-store availability before resolving\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\ndefer cancel()\nif _, err := store.Get(ctx, key); err != nil {\n    // store unreachable; skip resolve until it recovers\n}","typeGuard":null,"tryCatchPattern":"handle, err := manager.Resolve(ctx, key)\nif err != nil && strings.Contains(err.Error(), \"read winning sandbox binding\") {\n    // transient store read during race resolution\n    time.Sleep(50*time.Millisecond)\n    handle, err = manager.Resolve(ctx, key)\n}","preventionTips":["Deploy a health check on the binding store before admitting session traffic","Use short bounded retries around session resolve for store blips","Monitor store read latency; alert before it exceeds request budgets"],"tags":["go","distributed-race","binding-store","transient"],"backgroundTag":"binding-store-read-failure","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}