{"record":{"id":"2a2cfd52325cea78","repo":"moeru-ai/airi","slug":"cannot-close-a-dualsense-controller-while-it-is","errorCode":null,"errorMessage":"Cannot close a DualSense controller while it is ${this.#lifecycle}.","messagePattern":"Cannot close a DualSense controller while it is (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/input-playstation-dualsense-5/src/controller.ts","lineNumber":99,"sourceCode":"  async close(): Promise<void> {\n    if (this.#lifecycle === 'closed')\n      return\n    if (this.#lifecycle !== 'open')\n      throw new Error(`Cannot close a DualSense controller while it is ${this.#lifecycle}.`)\n\n    this.#lifecycle = 'closing'\n    this.#device.removeEventListener('inputreport', this.#handleInputReport)\n    try {\n      if (this.#device.opened)\n        await this.#device.close()\n    }\n    finally {\n      this.#lifecycle = 'closed'\n    }\n  }","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/moeru-ai/airi/blob/9c213115f8bd0fff9e6eabab02b077ac32da21be/packages/input-playstation-dualsense-5/src/controller.ts#L81-L117","documentation":"close() is only valid from the 'open' lifecycle state. The guard throws when close() is called while a transition is in progress ('opening' or 'closing'), i.e. another lifecycle operation still holds the device and closing now would race with it. Calling close() while already 'closed' returns silently and never reaches this error.","triggerScenarios":"Thrown at packages/input-playstation-dualsense-5/src/controller.ts:99 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Await the in-flight open()/close() promise before calling close() — the error message names the conflicting state.","Serialize lifecycle calls behind a single promise chain or mutex in the owner of the controller.","If close() was triggered by teardown (page unload, component unmount), guard against duplicate teardown paths sharing one controller."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"9c213115f8bd0fff9e6eabab02b077ac32da21be","analyzedAt":"2026-09-02T04:27:24.639Z","contentChangedAt":"2026-09-02T04:27:24.639Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}