{"record":{"id":"f9653b7d9ef57761","repo":"apache/seatunnel","slug":"checkpointid-is-already-set","errorCode":null,"errorMessage":"checkpointId is already set","messagePattern":"checkpointId is already set","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/flow/SourceFlowLifeCycle.java","lineNumber":640,"sourceCode":"        public static SchemaChangePhase createBeforePhase() {\n            return new SchemaChangePhase(PHASE_CHANGE_BEFORE);\n        }\n\n        public static SchemaChangePhase createAfterPhase() {\n            return new SchemaChangePhase(PHASE_CHANGE_AFTER);\n        }\n\n        public boolean isBeforePhase() {\n            return PHASE_CHANGE_BEFORE.equals(phase);\n        }\n\n        public boolean isAfterPhase() {\n            return PHASE_CHANGE_AFTER.equals(phase);\n        }\n\n        public void setCheckpointId(long checkpointId) {\n            if (this.checkpointId != -1) {\n                throw new IllegalStateException(\"checkpointId is already set\");\n            }\n            this.checkpointId = checkpointId;\n        }\n    }\n}\n","sourceCodeStart":622,"sourceCodeEnd":646,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/flow/SourceFlowLifeCycle.java#L622-L646","documentation":"SchemaChangePhase.setCheckpointId() only allows binding a checkpoint id once; if this.checkpointId is already set (not the -1 sentinel) it throws IllegalStateException. This guards the invariant that a single schema-change phase is associated with exactly one checkpoint barrier.","triggerScenarios":"setCheckpointId() called a second time on the same SchemaChangePhase instance, e.g. a duplicate barrier trigger or phase object reused across checkpoint cycles without being recreated.","commonSituations":"Duplicate barrier delivery after task retry; a code path re-triggering triggerBarrier for the same phase; custom engine patches that reuse phase objects.","solutions":["Ensure a new SchemaChangePhase is created for every schema-change cycle instead of reusing the old one.","Deduplicate barriers by checkpoint id before calling setCheckpointId.","If this is reproducible with no duplicate barrier, report/inspect the barrier replay logic in the task execution."],"exampleFix":"// before: reuse phase across checkpoints\nphase.setCheckpointId(newId); // throws if already set\n// after: recreate phase per cycle\nif (phase.getCheckpointId() != -1) {\n    phase = SchemaChangePhase.createBeforePhase();\n}\nphase.setCheckpointId(newId);","handlingStrategy":"validation","validationCode":"if (phase.getCheckpointId() == -1) { phase.setCheckpointId(id); }","typeGuard":"boolean isCheckpointIdUnset(SchemaChangePhase p) { return p.getCheckpointId() == -1; }","tryCatchPattern":"try { phase.setCheckpointId(id); } catch (IllegalStateException e) { if (e.getMessage().equals(\"checkpointId is already set\")) { /* duplicate barrier; ignore or recreate phase */ } else { throw e; } }","preventionTips":["Create a fresh SchemaChangePhase per schema-change cycle","Deduplicate barriers by checkpoint id","Never reuse phase objects across checkpoint cycles"],"tags":["checkpoint","schema-change","invariant","idempotency"],"backgroundTag":"internal-invariant-violation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}