{"record":{"id":"66633df6a579ff3a","repo":"conductor-oss/conductor","slug":"workflow-s-is-not-in-terminal-state-unable-to-r-66633d","errorCode":null,"errorMessage":"Workflow: %s is not in terminal state, unable to rerun.","messagePattern":"Workflow: (.+?) is not in terminal state, unable to rerun\\.","errorType":"exception","errorClass":"ConflictException","httpStatus":409,"severity":"error","filePath":"core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutorOps.java","lineNumber":2186,"sourceCode":"                failureWorkflow,\n                failureWorkflowVersion);\n    }\n\n    private boolean rerunWF(\n            String workflowId,\n            String taskId,\n            Map<String, Object> taskInput,\n            Map<String, Object> workflowInput,\n            String correlationId) {\n\n        // Get the workflow\n        WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true);\n        if (!workflow.getStatus().isTerminal()) {\n            String errorMsg =\n                    String.format(\n                            \"Workflow: %s is not in terminal state, unable to rerun.\", workflow);\n            LOGGER.error(errorMsg);\n            throw new ConflictException(errorMsg);\n        }\n        // If the task Id is null it implies that the entire workflow has to be rerun\n        if (taskId == null) {\n            // remove all tasks\n            workflow.getTasks().forEach(task -> executionDAOFacade.removeTask(task.getTaskId()));\n            workflow.setTasks(new ArrayList<>());\n            // Set workflow as RUNNING\n            workflow.setStatus(WorkflowModel.Status.RUNNING);\n            // Reset failure reason from previous run to default\n            workflow.setReasonForIncompletion(null);\n            workflow.setFailedTaskId(null);\n            workflow.setFailedReferenceTaskNames(new HashSet<>());\n            workflow.setFailedTaskNames(new HashSet<>());\n\n            if (correlationId != null) {\n                workflow.setCorrelationId(correlationId);\n            }\n            if (workflowInput != null) {","sourceCodeStart":2168,"sourceCodeEnd":2204,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutorOps.java#L2168-L2204","documentation":"Thrown by rerunWF() when the caller invokes the rerun/retry API on a workflow whose status is not terminal (i.e., not COMPLETED, FAILED, TERMINATED, or TIMED_OUT). Conductor only allows rerun on workflows that have finished their lifecycle; rerunning an active RUNNING or PAUSED workflow would corrupt in-flight task state. The message embeds the full WorkflowModel.toString() so you can see the current status inline.","triggerScenarios":"Calling WorkflowExecutor.rerun() (REST: PUT /api/workflow/{workflowId}/rerun or retry) while the workflow is in RUNNING, PAUSED, or any non-terminal status. Also triggered when a parent workflow initiates a recursive rerunWF on a sub-workflow that is still executing.","commonSituations":"Polling a workflow that is still executing and calling rerun prematurely. A UI 'Retry' button that does not check status first. Race conditions where the decider has not yet marked a failed workflow as terminal before the rerun call arrives.","solutions":["Check the workflow status via GET /api/workflow/{workflowId} and wait until it reaches a terminal status (COMPLETED, FAILED, TERMINATED, TIMED_OUT) before calling rerun.","If the workflow is stuck in RUNNING and you need to force-rerun, first terminate it via POST /api/workflow/{workflowId}/terminate, then rerun.","If the workflow is PAUSED, resume it (PUT /api/workflow/{workflowId}/resume) or terminate it before rerunning.","For sub-workflow reruns, ensure the parent workflow and all children are terminal before initiating a recursive rerun."],"exampleFix":"// before\nworkflowExecutor.rerun(workflowId, null, null, null, null);\n\n// after\nWorkflowModel wf = executionDAOFacade.getWorkflowModel(workflowId, false);\nif (!wf.getStatus().isTerminal()) {\n    throw new IllegalStateException(\"Cannot rerun: workflow is \" + wf.getStatus());\n}\nworkflowExecutor.rerun(workflowId, null, null, null, null);","handlingStrategy":"validation","validationCode":"// Before calling rerun, check terminal status\nWorkflowModel wf = executionDAOFacade.getWorkflowModel(workflowId, false);\nif (!wf.getStatus().isTerminal()) {\n    throw new IllegalStateException(\n        \"Cannot rerun workflow \" + workflowId + \" in status \" + wf.getStatus());\n}\nworkflowExecutor.rerun(workflowId, null, null, null, null);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always query workflow status before calling rerun/retry APIs.","Implement a status-gated retry button in UIs that disables when the workflow is not terminal.","For sub-workflow recursive reruns, validate the entire parent-child chain is terminal."],"tags":["rerun","workflow-status","conflict","terminal-state"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}