{"record":{"id":"1c276a3c16910e88","repo":"earendil-works/pi","slug":"session-sessionid-already-has-an-active-lease","errorCode":null,"errorMessage":"Session ${sessionId} already has an active lease","messagePattern":"Session (.+?) already has an active lease","errorType":"exception","errorClass":"PiSessionOwnershipError","httpStatus":null,"severity":"error","filePath":"packages/client/src/client.ts","lineNumber":384,"sourceCode":"\t\tif (!reconciliation) {\n\t\t\treconciliation = this.#request({ command: \"detach\", sessionId })\n\t\t\t\t.then(() => undefined)\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.#sessionCleanupRequired.delete(sessionId);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.#sessionReconciliations.delete(sessionId);\n\t\t\t\t});\n\t\t\tthis.#sessionReconciliations.set(sessionId, reconciliation);\n\t\t}\n\t\tawait reconciliation;\n\t\treturn true;\n\t}\n\n\t#reserveSessionLease(sessionId: string, mode: SessionLeaseMode): SessionLeaseToken {\n\t\tconst count = this.#sessionLeaseCounts.get(sessionId) ?? 0;\n\t\tif (mode === \"exclusive\" && count > 0) {\n\t\t\tthrow new PiSessionOwnershipError(sessionId, `Session ${sessionId} already has an active lease`);\n\t\t}\n\t\tif (mode === \"shared\" && this.#exclusiveSessionLeases.has(sessionId)) {\n\t\t\tthrow new PiSessionOwnershipError(sessionId, `Session ${sessionId} has an exclusive lease`);\n\t\t}\n\t\tconst token: SessionLeaseToken = { mode };\n\t\tthis.#sessionLeaseCounts.set(sessionId, count + 1);\n\t\tif (mode === \"exclusive\") this.#exclusiveSessionLeases.set(sessionId, token);\n\t\treturn token;\n\t}\n\n\t#releaseSessionLease(sessionId: string, token: SessionLeaseToken): void {\n\t\tconst count = this.#sessionLeaseCounts.get(sessionId) ?? 0;\n\t\tif (count <= 1) this.#sessionLeaseCounts.delete(sessionId);\n\t\telse this.#sessionLeaseCounts.set(sessionId, count - 1);\n\t\tif (this.#exclusiveSessionLeases.get(sessionId) === token) this.#exclusiveSessionLeases.delete(sessionId);\n\t}\n\n\t#invalidateSessionLeases(sessionId: string): void {","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/earendil-works/pi/blob/4af9d21d3b4d664e4a29fcabfec85171077248e3/packages/client/src/client.ts#L366-L402","documentation":"Error \"Session ${sessionId} already has an active lease\" thrown in earendil-works/pi.","triggerScenarios":"Thrown at packages/client/src/client.ts:384 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Release the existing active lease before acquiring a new one."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4af9d21d3b4d664e4a29fcabfec85171077248e3","analyzedAt":"2026-08-24T13:07:14.692Z","schemaVersion":2},"datasetVersion":"2026-08-24T17:17:21.512Z"}