{"record":{"id":"6ab5931cddf0acdd","repo":"MyCATApache/Mycat-Server","slug":"incrsequencezkhandler-should-be-loaded-first","errorCode":null,"errorMessage":"IncrSequenceZKHandler should be loaded first!","messagePattern":"IncrSequenceZKHandler should be loaded first!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/sequence/handler/IncrSequenceZKHandler.java","lineNumber":173,"sourceCode":"        Map<String, Map<String, String>> tableParaValMap = tableParaValMapThreadLocal.get();\n        if (tableParaValMap == null) {\n            try {\n                threadLocalLoad();\n            } catch (Exception e) {\n                LOGGER.error(\"Error caught while loding configuration within current thread:\" + e.getCause());\n            }\n            tableParaValMap = tableParaValMapThreadLocal.get();\n        }\n        Map<String, String> paraValMap = tableParaValMap.get(prefixName);\n        return paraValMap;\n    }\n\n    @Override\n    public Boolean fetchNextPeriod(String prefixName) {\n        InterProcessSemaphoreMutex interProcessSemaphoreMutex = interProcessSemaphoreMutexThreadLocal.get();\n        try {\n            if (interProcessSemaphoreMutex == null) {\n                throw new IllegalStateException(\"IncrSequenceZKHandler should be loaded first!\");\n            }\n            interProcessSemaphoreMutex.acquire();\n            Map<String, Map<String, String>> tableParaValMap = tableParaValMapThreadLocal.get();\n            if (tableParaValMap == null) {\n                throw new IllegalStateException(\"IncrSequenceZKHandler should be loaded first!\");\n            }\n            Map<String, String> paraValMap = tableParaValMap.get(prefixName);\n            if (paraValMap == null) {\n                throw new IllegalStateException(\"IncrSequenceZKHandler should be loaded first!\");\n            }\n            if (paraValMap.get(prefixName + KEY_MAX_NAME) == null) {\n                paraValMap.put(prefixName + KEY_MAX_NAME, props.getProperty(prefixName + KEY_MAX_NAME));\n            }\n            if (paraValMap.get(prefixName + KEY_MIN_NAME) == null) {\n                paraValMap.put(prefixName + KEY_MIN_NAME, props.getProperty(prefixName + KEY_MIN_NAME));\n            }\n            if (paraValMap.get(prefixName + KEY_CUR_NAME) == null) {\n                paraValMap.put(prefixName + KEY_CUR_NAME, props.getProperty(prefixName + KEY_CUR_NAME));","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/sequence/handler/IncrSequenceZKHandler.java#L155-L191","documentation":"fetchNextPeriod() requires per-thread state (the InterProcessSemaphoreMutex) that is only populated by handle() during load()/initializeZK(). If the mutex ThreadLocal is null when fetchNextPeriod runs, the ZK handler was never initialized on this thread, so it throws IllegalStateException. Without the lock it is unsafe to fetch a new ID period from ZooKeeper.","triggerScenarios":"Calling fetchNextPeriod (directly or via handle/getParaValMap -> threadLocalLoad) on a thread where IncrSequenceZKHandler.load() or initializeZK() was never run — e.g. ZkConfig/ZK URL missing so load() failed, or load() was skipped entirely.","commonSituations":"ZooKeeper unavailable at startup: load() catches the exception and only logs it, so the handler instance exists but was never initialized; calling nextId() before load(); using the handler from a worker thread that never ran threadLocalLoad().","solutions":["Ensure IncrSequenceZKHandler.load() is invoked (and succeeds) before any nextId()/fetchNextPeriod call","Verify ZK connectivity and ZkConfig cluster ID so initializeZK() completes instead of failing silently inside load()'s catch block","Call threadLocalLoad() on the current thread before using the handler if worker threads are involved"],"exampleFix":"// before\nIncrSequenceZKHandler.getInstance().nextId(\"ORDERS\"); // handler never loaded\n// after\nIncrSequenceZKHandler handler = IncrSequenceZKHandler.getInstance();\nhandler.load();\nlong id = handler.nextId(\"ORDERS\");","handlingStrategy":"validation","validationCode":"if (!zkHandlerInitialized) {\n    handler.load(); // must succeed before any nextId() call\n}\n// confirm load() did not fail: initializeZK errors are only logged, not rethrown","typeGuard":null,"tryCatchPattern":"try {\n    long id = handler.nextId(prefixName);\n} catch (IllegalStateException e) {\n    LOGGER.error(\"ZK sequence handler not initialized on this thread\", e);\n    handler.threadLocalLoad();\n    long id = handler.nextId(prefixName);\n}","preventionTips":["Always call load() at startup and verify ZK connectivity — load() swallows initializeZK() exceptions","Check startup logs for 'Error caught while initializing ZK'","Initialize handler state on every worker thread via threadLocalLoad()"],"tags":["zookeeper","initialization-order","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}