{"record":{"id":"7fe6e72b5dfc2bf5","repo":"apache/dolphinscheduler","slug":"the-workflow-instance-s-status-is-s-can-not-be","errorCode":null,"errorMessage":"The workflow instance: %s status is %s, can not be recovered","messagePattern":"The workflow instance: (.+?) status is (.+?), can not be recovered","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"warning","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/workflow/RecoverFailureTaskInstanceExecutorDelegate.java","lineNumber":48,"sourceCode":"\nimport lombok.Getter;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class RecoverFailureTaskInstanceExecutorDelegate\n        implements\n            IExecutorDelegate<RecoverFailureTaskInstanceExecutorDelegate.RecoverFailureTaskInstanceOperation, Void> {\n\n    @Autowired\n    private RegistryClient registryClient;\n\n    @Override\n    public Void execute(RecoverFailureTaskInstanceOperation recoverFailureTaskInstanceOperation) {\n        WorkflowInstance workflowInstance = recoverFailureTaskInstanceOperation.getWorkflowInstance();\n        if (!workflowInstance.getState().isFailure()) {\n            throw new ServiceException(\n                    String.format(\"The workflow instance: %s status is %s, can not be recovered\",\n                            workflowInstance.getName(), workflowInstance.getState()));\n        }\n\n        final Server masterServer = registryClient.getRandomServer(RegistryNodeType.MASTER).orElse(null);\n        if (masterServer == null) {\n            throw new ServiceException(\"no master server available\");\n        }\n        final WorkflowInstanceRecoverFailureTasksRequest recoverFailureTaskRequest =\n                WorkflowInstanceRecoverFailureTasksRequest.builder()\n                        .workflowInstanceId(workflowInstance.getId())\n                        .userId(recoverFailureTaskInstanceOperation.executeUser.getId())\n                        .build();\n\n        final WorkflowInstanceRecoverFailureTasksResponse recoverFailureTaskResponse = Clients\n                .withService(IWorkflowControlClient.class)\n                .withHost(masterServer.getHost() + \":\" + masterServer.getPort())\n                .triggerFromFailureTasks(recoverFailureTaskRequest);","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/workflow/RecoverFailureTaskInstanceExecutorDelegate.java#L30-L66","documentation":"Thrown when attempting to recover (rerun) failed tasks of a workflow instance that is not in a failure state. Recovery from failed tasks is only valid when workflowInstance.getState().isFailure(); otherwise the API refuses the operation.","triggerScenarios":"Calling the recover-failed-tasks API (RecoverFailureTaskInstanceExecutorDelegate.execute) on an instance whose state is running, success, stopped, killed, paused, etc.","commonSituations":"User clicks 'recover failed task' after the workflow already succeeded or was killed; UI state stale relative to actual instance state; script retries recovery on an already-recovered instance; confusing 'workflow success despite task failure' cases where the state is not FAILURE.","solutions":["Query the instance's current state first; only recover when state is failure","Refresh the UI/instance data — the state may have changed since it was displayed","If the instance is killed/stopped, use the appropriate resume/restart operation instead","Fix the underlying failure and use the correct operation for the current state"],"exampleFix":"// before\napi.recoverFailureTasks(instanceId, userId);\n// after\nWorkflowInstance wf = api.queryWorkflowInstance(instanceId);\nif (wf.getState().isFailure()) {\n    api.recoverFailureTasks(instanceId, userId);\n}","handlingStrategy":"validation","validationCode":"if (!workflowInstance.getState().isFailure()) {\n    throw new IllegalStateException(\"Instance state \" + workflowInstance.getState() + \" is not recoverable from failure\");\n}","typeGuard":"boolean recoverableFromFailure(WorkflowInstance wf) { return wf.getState().isFailure(); }","tryCatchPattern":"try { delegate.recoverFailureTasks(op); } catch (ServiceException e) { if (e.getMessage().contains(\"can not be recovered\")) { log.info(\"Instance not in failure state; skipping recovery\"); } else { throw e; } }","preventionTips":["Check state immediately before recovery calls","Refresh instance data after any state-changing operation","Route failed instances to recover-failure and killed instances to their own recovery path","Avoid caching instance state in long-running automation loops"],"tags":["dolphinscheduler","workflow-state","invalid-state-transition","recovery"],"backgroundTag":"invalid-state-transition","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}