flowable/flowable-engine · error · FlowableIllegalArgumentException
comment id is null
Error message
comment id is null
What it means
SaveCommentCmd requires the Comment to have an id, since it performs an update of an existing comment row. It throws FlowableIllegalArgumentException('comment id is null') when a comment with a null id is saved, indicating the caller is treating a new (unsaved) comment as an existing one.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SaveCommentCmd.java:43
/**
* @author Tijs Rademakers
*/
public class SaveCommentCmd implements Command<Void>, Serializable {
private static final long serialVersionUID = 1L;
protected CommentEntity comment;
public SaveCommentCmd(CommentEntity comment) {
this.comment = comment;
}
@Override
public Void execute(CommandContext commandContext) {
if (comment == null) {
throw new FlowableIllegalArgumentException("comment is null");
}
if (comment.getId() == null) {
throw new FlowableIllegalArgumentException("comment id is null");
}
CommentEntityManager commentEntityManager = CommandContextUtil.getCommentEntityManager(commandContext);
String eventMessage = comment.getFullMessage().replaceAll("\\s+", " ");
if (eventMessage.length() > 163) {
eventMessage = eventMessage.substring(0, 160) + "...";
}
comment.setMessage(eventMessage);
commentEntityManager.update(comment);
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Use taskService.createComment(taskId, processInstanceId, message) for new comments instead of saveComment.
- Ensure the Comment being saved was fetched from the engine so its id is populated.
- If constructing manually, insert it first so an id is generated.
Example fix
// before
CommentEntity c = new CommentEntityImpl();
c.setFullMessage("hello");
taskService.saveComment(c);
// after
taskService.addComment(taskId, processInstanceId, "hello"); Defensive patterns
Strategy: validation
Validate before calling
if (comment == null || comment.getId() == null) { throw new IllegalArgumentException("saveComment requires a persisted Comment with an id"); } Type guard
boolean isPersisted = comment != null && comment.getId() != null;
Try / catch
try {
taskService.saveComment(comment);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("comment id is null")) {
// create a new comment instead
taskService.addComment(taskId, processInstanceId, comment.getFullMessage());
}
} Prevention
- Only call saveComment on comments fetched from the engine
- Use createComment for comments you construct yourself
- Keep the id field intact through any serialization/copying
When it happens
Trigger: Calling TaskService.saveComment with a Comment built manually (never persisted) or from createComment where id was never assigned.
Common situations: Developers constructing a new Comment object in code and calling saveComment instead of createComment; deserialization dropping the id field; copying a comment entity without its id.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/140197d3a901fbab.
Report an issue: GitHub.