{"record":{"id":"80b805590a70e5bc","repo":"flowable/flowable-engine","slug":"task-taskid-is-not-suspended-so-can-t-be-activ","errorCode":null,"errorMessage":"Task ${taskId} is not suspended, so can't be activated","messagePattern":"Task (.+?) is not suspended, so can't be activated","errorType":"validation","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ActivateTaskCmd.java","lineNumber":62,"sourceCode":"    public Void execute(CommandContext commandContext) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        \n        if (taskId == null) {\n            throw new FlowableIllegalArgumentException(\"taskId is null\");\n        }\n\n        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n\n        if (task == null) {\n            throw new FlowableObjectNotFoundException(\"Cannot find task with id \" + taskId, Task.class);\n        }\n\n        if (task.isDeleted()) {\n            throw new FlowableException(\"Task \" + taskId + \" is already deleted\");\n        }\n\n        if (!task.isSuspended()) {\n            throw new FlowableException(\"Task \" + taskId + \" is not suspended, so can't be activated\");\n        }\n        \n        Clock clock = cmmnEngineConfiguration.getClock();\n        Date updateTime = clock.getCurrentTime();\n        task.setSuspendedTime(null);\n        task.setSuspendedBy(null);\n        if (task.getInProgressStartTime() != null) {\n            task.setState(Task.IN_PROGRESS);\n        } else if (task.getClaimTime() != null) {\n            task.setState(Task.CLAIMED);\n        } else {\n            task.setState(Task.CREATED);\n        }\n        task.setSuspensionState(SuspensionState.ACTIVE.getStateCode());\n        \n        List<PlanItemInstanceEntity> planItemInstances = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findByReferenceId(task.getId());\n        \n        if (planItemInstances != null && !planItemInstances.isEmpty()) {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ActivateTaskCmd.java#L44-L80","documentation":"Flowable CMMN throws this when ActivateTaskCmd is executed against a plan item / task whose entity is not currently suspended. Activation (clearing suspendedTime/suspendedBy) is only meaningful for suspended tasks, so the command fails fast with a FlowableException to prevent an invalid state transition.","triggerScenarios":"Calling CmmnTaskService.activateTask(taskId) (or the ActivateTaskCmd directly) on a task whose TaskEntity.isSuspended() is false — e.g. the task was never suspended, or it was already activated in a prior call.","commonSituations":"Double-invocation of activation after a retry, activating tasks in bulk where only some are suspended, race between two threads/instances where one already activated the task, or confusing suspend with other state changes like completion.","solutions":["Check task.isSuspended() (via TaskService.createTaskQuery().taskId(id).singleResult()) before calling activateTask","Skip or log tasks already active instead of activating unconditionally","Serialize activation calls (idempotent handling) so concurrent callers don't double-activate","Verify the correct taskId was passed — a wrong/stale id may point at a never-suspended task"],"exampleFix":"// before\ntaskService.activateTask(taskId);\n// after\nTask task = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (task != null && task.isSuspended()) {\n    taskService.activateTask(taskId);\n}","handlingStrategy":"validation","validationCode":"Task t = cmmnTaskService.createTaskQuery().taskId(taskId).singleResult();\nif (t == null) throw new IllegalArgumentException(\"task not found: \" + taskId);\nboolean canActivate = t.isSuspended();","typeGuard":"boolean canActivate(Task t) { return t != null && t.isSuspended(); }","tryCatchPattern":"try {\n    cmmnTaskService.activateTask(taskId);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"not suspended\")) { /* already active: skip/log */ }\n    else throw e;\n}","preventionTips":["Query isSuspended() before activating","Make activation idempotent — treat 'not suspended' as a no-op in retries","Avoid activating whole batches blindly; filter by suspended state in the task query","Guard against concurrent activation with locking or single writer"],"tags":["cmmn","state-transition","task-lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}