{"record":{"id":"fe8ffa12394402a8","repo":"flowable/flowable-engine","slug":"comment-with-id-doesn-t-exists","errorCode":null,"errorMessage":"Comment with id '' doesn't exists.","messagePattern":"Comment with id '' doesn't exists\\.","errorType":"exception","errorClass":"FlowableObjectNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteCommentCmd.java","lineNumber":56,"sourceCode":"    protected String processInstanceId;\n    protected String commentId;\n\n    public DeleteCommentCmd(String taskId, String processInstanceId, String commentId) {\n        this.taskId = taskId;\n        this.processInstanceId = processInstanceId;\n        this.commentId = commentId;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        CommentEntityManager commentManager = processEngineConfiguration.getCommentEntityManager();\n\n        if (commentId != null) {\n            // Delete for an individual comment\n            Comment comment = commentManager.findComment(commentId);\n            if (comment == null) {\n                throw new FlowableObjectNotFoundException(\"Comment with id '\" + commentId + \"' doesn't exists.\", Comment.class);\n            }\n\n            if (comment.getProcessInstanceId() != null) {\n                ExecutionEntity execution = (ExecutionEntity) processEngineConfiguration.getExecutionEntityManager().findById(comment.getProcessInstanceId());\n                if (execution != null && Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, execution.getProcessDefinitionId())) {\n                    Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();\n                    compatibilityHandler.deleteComment(commentId, taskId, processInstanceId);\n                    return null;\n                }\n\n            } else if (comment.getTaskId() != null) {\n                Task task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(comment.getTaskId());\n                if (task != null && task.getProcessDefinitionId() != null && Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {\n                    Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();\n                    compatibilityHandler.deleteComment(commentId, taskId, processInstanceId);\n                    return null;\n                }\n            }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteCommentCmd.java#L38-L74","documentation":"DeleteCommentCmd deletes a comment by id; if CommentEntityManager.findComment(commentId) returns null the command throws FlowableObjectNotFoundException with Comment.class. The comment id must refer to an existing persisted comment.","triggerScenarios":"Calling TaskService.deleteComment(commentId) with an id that doesn't exist in ACT_HI_COMMENT — already deleted, invalid id, or id from a different database/engine.","commonSituations":"Client deletes a comment twice (double click / retry); stale id after a comment was removed by another user; passing a taskId/processInstanceId where a commentId is expected.","solutions":["Verify existence before deleting: taskService.getProcessInstanceComments / getTaskComments and match the comment id, then delete only if found.","Make the delete idempotent: catch FlowableObjectNotFoundException and treat the comment as already removed.","Confirm the id passed is the comment's persisted id, not the task id."],"exampleFix":"// before\ntaskService.deleteComment(commentId);\n// after\ntry {\n    taskService.deleteComment(commentId);\n} catch (FlowableObjectNotFoundException e) {\n    // comment already deleted; ignore\n}","handlingStrategy":"try-catch","validationCode":"List<Comment> comments = taskService.getTaskComments(taskId);\nboolean exists = comments.stream().anyMatch(c -> commentId.equals(c.getId()));","typeGuard":null,"tryCatchPattern":"try {\n    taskService.deleteComment(commentId);\n} catch (FlowableObjectNotFoundException e) {\n    log.info(\"Comment {} already deleted\", commentId);\n}","preventionTips":["Treat comment deletion as idempotent on the client (disable button after first click)","Refresh comment lists after any delete to avoid stale ids","Verify you pass the comment id, not the task or process instance id"],"tags":["flowable","comment","delete"],"backgroundTag":"entity-not-found","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"}