{"record":{"id":"8b547ca9291905a0","repo":"Tencent/WeKnora","slug":"cleanup-losing-remote-sandbox-w","errorCode":null,"errorMessage":"cleanup losing remote sandbox: %w","messagePattern":"cleanup losing remote sandbox: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_lifecycle.go","lineNumber":407,"sourceCode":"\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,\n) (RemoteSandboxHandle, error) {\n\twinner, err := l.readBinding(ctx, key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif winner == nil {\n\t\treturn nil, errors.New(\"sandbox binding create lost without a winner\")\n\t}","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_lifecycle.go#L389-L425","documentation":"After losing the binding-create race, createAndBind must delete the just-created remote sandbox that it did not win. If the provider Delete (via cleanupCreated) fails, the error is wrapped so the caller knows a losing/leaked sandbox may remain in the provider account.","triggerScenarios":"Coordinator loses a concurrent binding race and its cleanupCreated -> client.Delete call against the remote provider fails (network error, provider 5xx, timeout, sandbox already terminating in a way not recognized as replaceable).","commonSituations":"Provider API instability or rate limits during concurrent allocation storms; short cleanup context timeouts; orphaned sandboxes accumulating in the provider console after repeated failures.","solutions":["Inspect the wrapped provider error and retry the session resolve — cleanup may succeed on retry","Check the provider dashboard for leaked/orphaned sandboxes from the failed session key and delete them manually","Increase cleanup timeout / reduce concurrent allocation pressure","Verify the client's credentials have delete permission for the sandbox"],"exampleFix":"// before\nhandle, err := manager.Resolve(ctx, sessionKey)\n// after\nif err != nil && strings.Contains(err.Error(), \"cleanup losing remote sandbox\") {\n    // losing sandbox cleanup failed; retry, then reconcile leaked sandboxes\n    handle, err = manager.Resolve(ctx, sessionKey)\n}","handlingStrategy":"retry","validationCode":"// Check provider health before concurrent allocations\nif err := client.Health(ctx); err != nil { /* defer workloads */ }","typeGuard":null,"tryCatchPattern":"handle, err := manager.Resolve(ctx, key)\nif err != nil && strings.Contains(err.Error(), \"cleanup losing remote sandbox\") {\n    // retry resolve; leaked sandbox cleanup may succeed on retry\n    handle, err = manager.Resolve(ctx, key)\n}","preventionTips":["Set generous cleanup timeouts in the sandbox config","Monitor provider delete-failure rates and rate limits","Periodically reconcile provider-side sandboxes against the binding store to catch leaks"],"tags":["go","remote-provider","cleanup","sandbox-leak","concurrency"],"backgroundTag":"remote-sandbox-cleanup-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}