{"record":{"id":"35ce8ee48efa7859","repo":"paperclipai/paperclip","slug":"an-adapter-login-session-is-already-active-for-thi","errorCode":null,"errorMessage":"An adapter login session is already active for this company and adapter.","messagePattern":"An adapter login session is already active for this company and adapter\\.","errorType":"http","errorClass":"AdapterAuthSessionConflictError","httpStatus":409,"severity":"error","filePath":"server/src/services/codex-device-login-service.ts","lineNumber":469,"sourceCode":"        await db.insert(adapterAuthSessions).values({\n          id: input.id,\n          companyId: input.companyId,\n          environmentId: input.environmentId,\n          adapterType: input.adapterType,\n          startedByUserId: input.startedByUserId,\n          // The unified table requires a unique public session id. The service\n          // builds it from a CSPRNG and returns it to the client, so the store\n          // persists that value here. It never uses the internal id, a timestamp,\n          // or a counter.\n          publicSessionId: input.publicSessionId,\n          status: \"starting\",\n          expiresAt: input.expiresAt,\n          createdAt: input.at,\n          updatedAt: input.at,\n        });\n      } catch (error) {\n        if (isUniqueViolation(error)) {\n          throw new AdapterAuthSessionConflictError();\n        }\n        throw error;\n      }\n    },\n    async recordLeaseAcquired(input) {\n      await db\n        .update(adapterAuthSessions)\n        .set({ providerLeaseId: input.providerLeaseId, updatedAt: input.at })\n        .where(eq(adapterAuthSessions.id, input.sessionId));\n    },\n    async setStatus(input) {\n      await db\n        .update(adapterAuthSessions)\n        .set(buildStatusPatch(input))\n        .where(eq(adapterAuthSessions.id, input.sessionId));\n    },\n    async compareAndSetStatus(input) {\n      // The conditional write. It changes the row only when the current status is","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/codex-device-login-service.ts#L451-L487","documentation":"Conflict guard when inserting a new adapterAuthSessions row: the unified sessions table already has an active (non-terminal) login session for the same company and adapterType. The unique-active-session invariant means a second concurrent login cannot be started; finish or cancel the existing session first.","triggerScenarios":"Thrown at server/src/services/codex-device-login-service.ts:437 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Wait for or cancel the active login session for this company and adapter before starting a new one."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}