{"record":{"id":"91fc5515c46f3f03","repo":"Tencent/WeKnora","slug":"recheck-owning-session-w","errorCode":null,"errorMessage":"recheck owning session: %w","messagePattern":"recheck owning session: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_lifecycle.go","lineNumber":370,"sourceCode":"\t\t}\n\t\tfor metadataKey, value := range l.metadata(key) {\n\t\t\trequest.Metadata[metadataKey] = value\n\t\t}\n\t}\n\trequest.EnvVars = cloneMetadata(l.createRequest.EnvVars)\n\n\thandle, err := l.client.Create(ctx, request)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create remote sandbox: %w\", err)\n\t}\n\tif err := l.validateHandle(handle, \"\"); err != nil {\n\t\treturn nil, errors.Join(err, l.cleanupCreated(ctx, handle))\n\t}\n\n\texists, checkErr := l.sessionChecker.SessionExists(ctx, key)\n\tif checkErr != nil {\n\t\treturn nil, errors.Join(\n\t\t\tfmt.Errorf(\"recheck owning session: %w\", checkErr),\n\t\t\tl.cleanupCreated(ctx, handle),\n\t\t)\n\t}\n\tif !exists {\n\t\treturn nil, errors.Join(ErrSandboxSessionDeleted, l.cleanupCreated(ctx, handle))\n\t}\n\n\tbinding := l.newBinding(\n\t\tkey,\n\t\thandle.ID(),\n\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),","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_lifecycle.go#L352-L388","documentation":"After creating a remote sandbox, the lifecycle re-checks that the owning session still exists via sessionChecker.SessionExists. If that check itself errors, the fresh sandbox is cleaned up and 'recheck owning session: %w' is returned — the library will not keep a newly created sandbox when it cannot confirm the session is still alive. This prevents leaking sandboxes for sessions deleted during creation.","triggerScenarios":"sessionChecker.SessionExists(ctx, key) returns an error right after a successful Create — the session store backend is unavailable, the read times out, or permissions on the session store fail. The error is joined with cleanupCreated's error via errors.Join.","commonSituations":"Session store (database/KV) outage or migration concurrent with sandbox creation; read timeout under load; revocation of read permissions between session creation and sandbox creation; misconfigured sessionChecker pointing at the wrong backend.","solutions":["Inspect the wrapped error (and any joined cleanup error) for session-store backend detail","Verify session-store availability and read permissions","Retry the whole resolve operation once the session store recovers","Confirm the sessionChecker is configured for the correct store/environment"],"exampleFix":"// before\nchecker := NewStoreSessionChecker(kvClient, \"wrong-namespace\")\n// after\nchecker := NewStoreSessionChecker(kvClient, sessionsNamespace) // matches where sessions are written","handlingStrategy":"retry","validationCode":"// confirm the session exists and the session store is readable before resolving\nif ok, err := sessionChecker.SessionExists(ctx, key); err != nil || !ok {\n    return fmt.Errorf(\"session %s not resolvable: (exists=%v, err=%v)\", key, ok, err)\n}","typeGuard":null,"tryCatchPattern":"handle, err := session.Resolve(ctx, key)\nif err != nil && strings.HasPrefix(err.Error(), \"recheck owning session:\") {\n    // sandbox was cleaned up automatically; safe to retry once store recovers\n    err = retryWithBackoff(ctx, 3, func() error { handle, err = session.Resolve(ctx, key); return err })\n}","preventionTips":["Monitor session-store availability; creation and check share its fate","Point sessionChecker at the same backend/namespace that writes sessions","Avoid deleting sessions concurrently with sandbox creation, or accept the cleanup","Set sane store read timeouts so transient slowness doesn't abort creation"],"tags":["storage","session-store","race-condition","cleanup"],"backgroundTag":"session-store-unavailable","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}