flowable/flowable-engine · error · FlowableObjectNotFoundException
Task '' does not have a comment with id ''.
Error message
Task '' does not have a comment with id ''.
What it means
Reading a task comment via GET /runtime/tasks/{taskId}/comments/{commentId} throws FlowableObjectNotFoundException when the comment id does not exist or exists but belongs to a different task. The comment is looked up by id and its taskId must match the requested task.
Solutions
- Verify the commentId exists via GET /runtime/tasks/{taskId}/comments and use one from the list
- Confirm the comment belongs to the same taskId in the URL path
- Re-fetch the comment list if the comment was recently deleted
Defensive patterns
Strategy: try-catch
Validate before calling
const comments = await get(`/runtime/tasks/${taskId}/comments`);
if (!comments.some(c => c.id === commentId)) return null; Try / catch
try { ... } catch (e) { if (e.status === 404) return null; throw e; } Prevention
- Always resolve comment ids from the task's comment list
- Never cache comment ids across tasks
- Treat 404 as 'already gone' in cleanup jobs
When it happens
Trigger: GET /runtime/tasks/{taskId}/comments/{commentId} where commentId is unknown, already deleted, or attached to another task's id.
Common situations: Stale ids cached by a client after comment deletion; copying a comment id from another task; historic-task endpoint used with a comment on the runtime task of a different id.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Could not find a app model json with id
- Could not find a deployment with id
- Could not find a milestone instance with id
- Could not find a plan item instance with id
- Could not find a resource with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a1f34f26ac00b3ba.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskCommentResource.java:54
* @author Frederik Heremans
*/
@RestController
@Api(tags = { "Task Comments" }, authorizations = { @Authorization(value = "basicAuth") })
public class TaskCommentResource extends TaskBaseResource {
@ApiOperation(value = " Get a comment on a task", tags = { "Task Comments" }, nickname = "getTaskComment")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Indicates the task and comment were found and the comment is returned."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found or the tasks does not have a comment with the given ID.")
})
@GetMapping(value = "/runtime/tasks/{taskId}/comments/{commentId}", produces = "application/json")
public CommentResponse getComment(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @ApiParam(name = "commentId") @PathVariable("commentId") String commentId) {
HistoricTaskInstance task = getHistoricTaskFromRequest(taskId);
Comment comment = taskService.getComment(commentId);
if (comment == null || !task.getId().equals(comment.getTaskId())) {
throw new FlowableObjectNotFoundException("Task '" + task.getId() + "' does not have a comment with id '" + commentId + "'.", Comment.class);
}
return restResponseFactory.createRestComment(comment);
}
@ApiOperation(value = "Delete a comment on a task", tags = { "Task Comments" }, nickname = "deleteTaskComment", code = 204)
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Indicates the task and comment were found and the comment is deleted. Response body is left empty intentionally."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found or the tasks does not have a comment with the given ID.")
})
@DeleteMapping(value = "/runtime/tasks/{taskId}/comments/{commentId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteComment(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @ApiParam(name = "commentId") @PathVariable("commentId") String commentId) {
// Check if task exists
Task task = getTaskFromRequestWithoutAccessCheck(taskId);
Comment comment = taskService.getComment(commentId);View on GitHub (pinned to d6d39ce1c6)