{"record":{"id":"d9dc6466c9ada56d","repo":"flowable/flowable-engine","slug":"cannot-add-a-comment-to-a-suspended-execution-d9dc64","errorCode":null,"errorMessage":"Cannot add a comment to a suspended execution","messagePattern":"Cannot add a comment to a suspended execution","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddCommentCmd.java","lineNumber":76,"sourceCode":"\n            if (task == null) {\n                throw new ActivitiObjectNotFoundException(\"Cannot find task with id \" + taskId, Task.class);\n            }\n\n            if (task.isSuspended()) {\n                throw new ActivitiException(getSuspendedTaskException());\n            }\n        }\n\n        if (processInstanceId != null) {\n            ExecutionEntity execution = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);\n\n            if (execution == null) {\n                throw new ActivitiObjectNotFoundException(\"execution \" + processInstanceId + \" doesn't exist\", Execution.class);\n            }\n\n            if (execution.isSuspended()) {\n                throw new ActivitiException(getSuspendedExceptionMessage());\n            }\n        }\n\n        String userId = Authentication.getAuthenticatedUserId();\n        CommentEntity comment = new CommentEntity();\n        comment.setUserId(userId);\n        comment.setType((type == null) ? CommentEntity.TYPE_COMMENT : type);\n        comment.setTime(commandContext.getProcessEngineConfiguration().getClock().getCurrentTime());\n        comment.setTaskId(taskId);\n        comment.setProcessInstanceId(processInstanceId);\n        comment.setAction(Event.ACTION_ADD_COMMENT);\n\n        String eventMessage = message.replaceAll(\"\\\\s+\", \" \");\n        if (eventMessage.length() > 163) {\n            eventMessage = eventMessage.substring(0, 160) + \"...\";\n        }\n        comment.setMessage(eventMessage);\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddCommentCmd.java#L58-L94","documentation":"AddCommentCmd.execute rejects adding a comment to an execution (process instance) that is suspended, via getSuspendedExceptionMessage(). Suspended process instances are read-mostly; comment writes are treated as a state change and blocked.","triggerScenarios":"Calling TaskService.addComment(taskId, processInstanceId, message) where the referenced process instance is in suspension state SUSPENDED (after suspendProcessInstanceById or via a suspended process definition).","commonSituations":"Audit/annotation jobs run while the instance is administratively paused; users post notes in a UI without checking the instance's suspension state; suspend/activate windows during maintenance.","solutions":["Activate the instance first: runtimeService.activateProcessInstanceById(processInstanceId), then add the comment.","Check suspension before commenting: runtimeService.createProcessInstanceQuery().processInstanceId(pid).singleResult().isSuspended().","Queue the comment and post it after activation if suspension is temporary."],"exampleFix":"// before\ntaskService.addComment(taskId, processInstanceId, \"note\");\n// after\nProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();\nif (pi != null && !pi.isSuspended()) {\n    taskService.addComment(taskId, processInstanceId, \"note\");\n}","handlingStrategy":"validation","validationCode":"ProcessInstance pi = runtimeService.createProcessInstanceQuery()\n    .processInstanceId(processInstanceId).singleResult();\nif (pi != null && pi.isSuspended()) {\n    throw new IllegalStateException(\"Process instance \" + processInstanceId + \" is suspended\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    taskService.addComment(taskId, processInstanceId, message);\n} catch (ActivitiException e) {\n    if (\"Cannot add a comment to a suspended execution\".equals(e.getMessage())) {\n        commentQueue.add(message); // post after activation\n    } else { throw e; }\n}","preventionTips":["Check ProcessInstance.isSuspended() before writes on the instance","Queue or buffer audit-style writes during suspension windows","Activate instances before resuming batch annotation jobs"],"tags":["suspended-execution","comment","invalid-state-transition","activiti"],"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-18T11:17:12.947Z"}