{"record":{"id":"03ab36fd39c960c7","repo":"binarywang/WxJava","slug":"invalidate-session-already-invalidated","errorCode":null,"errorMessage":"invalidate: Session already invalidated","messagePattern":"invalidate: Session already invalidated","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"warning","filePath":"weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java","lineNumber":133,"sourceCode":"\n    // Validate our current state\n    if (!isValidInternal()) {\n      throw new IllegalStateException(SM.getString(\"sessionImpl.setAttribute.ise\", getIdInternal()));\n    }\n\n    this.attributes.put(name, value);\n\n  }\n\n  @Override\n  public void removeAttribute(String name) {\n    removeAttributeInternal(name);\n  }\n\n  @Override\n  public void invalidate() {\n    if (!isValidInternal()) {\n      throw new IllegalStateException(SM.getString(\"sessionImpl.invalidate.ise\"));\n    }\n\n    // Cause this session to expire\n    expire();\n\n  }\n\n  @Override\n  public WxSession getSession() {\n    if (this.facade == null) {\n      this.facade = new StandardSessionFacade(this);\n    }\n\n    return this.facade;\n  }\n\n  /**\n   * Return the <code>isValid</code> flag for this session without any expiration","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java#L115-L151","documentation":"StandardSession.invalidate throws IllegalStateException if the session is already invalid. invalidate() is meant to be called exactly once; calling it again (or after expiry) is rejected. Internally it calls expire() to clear attributes and mark the session dead.","triggerScenarios":"Calling session.invalidate() a second time, or calling it after the session already expired via maxInactiveInterval.","commonSituations":"Cleanup code that invalidates defensively on every request without checking validity first; a timeout-driven expiry racing with an explicit invalidate(); error-handling paths that invalidate then re-attempt.","solutions":["Guard invalidate() with isValid(): only invalidate live sessions.","Make invalidation idempotent at the call site (wrap in try/catch IllegalStateException).","Ensure only one owner (router/manager) invalidates a session to avoid double-invalidation races."],"exampleFix":"// before\nsession.invalidate(); // throws on second call\n\n// after\nif (session.isValid()) {\n  session.invalidate();\n}","handlingStrategy":"validation","validationCode":"if (session.isValid()) {\n  session.invalidate();\n}","typeGuard":"private static boolean sessionAccessible(WxSession s) {\n  return s != null && s.isValid();\n}","tryCatchPattern":"try {\n  session.invalidate();\n} catch (IllegalStateException ignored) {\n  // already invalidated — nothing to do\n}","preventionTips":["Guard invalidate() with isValid() so it is called at most once.","Centralise session invalidation in one owner to avoid races.","Make cleanup paths idempotent by swallowing the already-invalid case."],"tags":["session","invalidated","lifecycle","idempotency"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}