{"record":{"id":"7fbc086631fa3d78","repo":"apache/seatunnel","slug":"pipelinefullname-reset-state-failed-only-end-s","errorCode":null,"errorMessage":"${pipelineFullName} reset state failed, only end state can be reset, current is ${pipelineState}","messagePattern":"(.+?) reset state failed, only end state can be reset, current is (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/dag/physical/SubPlan.java","lineNumber":462,"sourceCode":"                    pipelineFullName,\n                    targetState);\n            return;\n        }\n        stateTimestamps[targetState.ordinal()] = System.currentTimeMillis();\n        runningJobStateTimestampsIMap.set(pipelineLocation, stateTimestamps);\n    }\n\n    private void resetPipelineState() throws Exception {\n        RetryUtils.retryWithException(\n                () -> {\n                    PipelineStatus pipelineState = getPipelineState();\n                    if (!pipelineState.isEndState()) {\n                        String message =\n                                String.format(\n                                        \"%s reset state failed, only end state can be reset, current is %s\",\n                                        getPipelineFullName(), pipelineState);\n                        log.error(message);\n                        throw new IllegalStateException(message);\n                    }\n                    log.info(\n                            String.format(\n                                    \"Reset pipeline %s state to %s\",\n                                    getPipelineFullName(), PipelineStatus.CREATED));\n                    updateStateTimestamps(PipelineStatus.CREATED);\n                    runningJobStateIMap.set(pipelineLocation, PipelineStatus.CREATED);\n                    this.currPipelineStatus = PipelineStatus.CREATED;\n                    log.info(\n                            String.format(\n                                    \"Reset pipeline %s state to %s complete\",\n                                    getPipelineFullName(), PipelineStatus.CREATED));\n                    return null;\n                },\n                new RetryUtils.RetryMaterial(\n                        Constant.OPERATION_RETRY_TIME,\n                        true,\n                        exception -> ExceptionUtil.isOperationNeedRetryException(exception),","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/dag/physical/SubPlan.java#L444-L480","documentation":"SubPlan.resetPipelineState only permits resetting a pipeline that has reached a terminal PipelineStatus, since reset rewinds it to CREATED for job restore. Resetting a running or transitioning pipeline would corrupt scheduling, so an IllegalStateException is thrown.","triggerScenarios":"Calling SubPlan.reset while the pipeline is RUNNING, SCHEDULED, FAILING, or CANCELING; restoring a job before all pipelines finished their shutdown.","commonSituations":"Resubmitting a savepoint-restore while pipelines are still cancelling; double-submit of the same job id; race between job restore and pipeline shutdown completion.","solutions":["Wait for all pipelines to reach an end state before calling reset","Fully cancel the job and await its JobResult prior to restore/reset","Check pipeline states in logs/REST API before invoking reset","If a pipeline is stuck in a transitional state, find the hung task and force cleanup first"],"exampleFix":"// before\nsubPlan.reset(); // pipeline still CANCELING\n// after\npipelineFuture.join(); // wait for PipelineExecutionState (end state)\nsubPlan.reset();","handlingStrategy":"validation","validationCode":"if (!subPlan.getPipelineState().isEndState()) { throw new IllegalStateException(\"pipeline must be terminal before reset\"); }","typeGuard":"boolean canResetPipeline(PipelineStatus s) { return s.isEndState(); }","tryCatchPattern":"try { subPlan.reset(); } catch (IllegalStateException e) { if (e.getMessage().contains(\"only end state can be reset\")) { /* defer reset until shutdown completes */ } else { throw e; } }","preventionTips":["Reset only after pipelineFuture completes","Fully cancel pipelines before restore","Watch for pipelines stuck in transitional states"],"tags":["zeta-engine","pipeline-state","reset","state-machine"],"backgroundTag":"invalid-state-transition","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"}