{"record":{"id":"c1d751f0ca1f7a02","repo":"Tencent/WeKnora","slug":"list-owned-remote-sandboxes-w","errorCode":null,"errorMessage":"list owned remote sandboxes: %w","messagePattern":"list owned remote sandboxes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_lifecycle.go","lineNumber":282,"sourceCode":"\tif err := l.validateHandle(handle, binding.SandboxID); err != nil {\n\t\treturn nil, false, err\n\t}\n\treturn handle, false, nil\n}\n\nfunc (l *remoteSessionLifecycle) recoverOwnedSandbox(\n\tctx context.Context,\n\tkey SessionSandboxKey,\n) (RemoteSandboxHandle, bool, error) {\n\tcapabilities := l.client.Capabilities()\n\tif !capabilities.SupportsMetadata || !capabilities.SupportsListSandboxes {\n\t\treturn nil, false, nil\n\t}\n\n\tmetadata := l.metadata(key)\n\tsummaries, err := l.client.List(ctx, RemoteListFilter{Metadata: metadata})\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"list owned remote sandboxes: %w\", err)\n\t}\n\tsort.Slice(summaries, func(i, j int) bool {\n\t\tleft, right := summaries[i], summaries[j]\n\t\tif left.StartedAt.Equal(right.StartedAt) {\n\t\t\treturn left.ID < right.ID\n\t\t}\n\t\tif left.StartedAt.IsZero() {\n\t\t\treturn false\n\t\t}\n\t\tif right.StartedAt.IsZero() {\n\t\t\treturn true\n\t\t}\n\t\treturn left.StartedAt.Before(right.StartedAt)\n\t})\n\n\tfor _, summary := range summaries {\n\t\tif summary.ID == \"\" || summary.State == RemoteStateTerminal {\n\t\t\tcontinue","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_lifecycle.go#L264-L300","documentation":"This error wraps a failure from client.List when the lifecycle tries to recover an orphaned sandbox by listing sandboxes matching the session's metadata. If the provider's List call fails (and the error is not otherwise handled), recovery is aborted with 'list owned remote sandboxes: %w' instead of silently creating a duplicate sandbox.","triggerScenarios":"client.List(ctx, RemoteListFilter{Metadata: metadata}) returns an error during resolveLocked's recovery path — provider API errors, network failures, malformed metadata filter rejected by the provider, or auth errors. Only reached when the client reports SupportsMetadata and SupportsListSandboxes capabilities.","commonSituations":"Provider does not actually support metadata filtering despite advertising the capability; metadata filter values contain characters the provider rejects; rate limiting on List; API outage; credentials lacking list permissions.","solutions":["Inspect the wrapped error for provider-specific filter validation messages and simplify/normalize the metadata values","Confirm the provider genuinely supports metadata-filtered listing or disable the capability advertisement","Check IAM/permissions for the list-sandboxes API","Retry with backoff if the wrapped error is transient (5xx/throttle)"],"exampleFix":"// before\nRemoteListFilter{Metadata: map[string]string{\"session\": keyWithSpaces}}\n// after\nRemoteListFilter{Metadata: map[string]string{\"session\": sanitize(key)}} // provider-safe values","handlingStrategy":"retry","validationCode":"// confirm the client really supports metadata listing before relying on recovery\ncaps := client.Capabilities()\nif !caps.SupportsMetadata || !caps.SupportsListSandboxes { /* skip recovery expectations */ }","typeGuard":null,"tryCatchPattern":"handle, err := session.Resolve(ctx, key)\nif err != nil && strings.HasPrefix(err.Error(), \"list owned remote sandboxes:\") {\n    err = retryWithBackoff(ctx, 3, func() error { handle, err = session.Resolve(ctx, key); return err })\n}","preventionTips":["Keep metadata values provider-safe (lowercase, no special characters)","Rate-limit List calls in hot loops","Grant the token list-sandboxes permission","Assert provider capabilities in an integration smoke test"],"tags":["network","provider-api","sandbox-recovery","list-filter"],"backgroundTag":"list-remotes-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}