{"record":{"id":"cde0e832a993397d","repo":"flowable/flowable-engine","slug":"task-not-found","errorCode":null,"errorMessage":"task not found","messagePattern":"task not found","errorType":"exception","errorClass":"FlowableObjectNotFoundException","httpStatus":404,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetIdentityLinksForTaskCmd.java","lineNumber":48,"sourceCode":" * @author Falko Menge\n */\npublic class GetIdentityLinksForTaskCmd implements Command<List<IdentityLink>>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    protected String taskId;\n\n    public GetIdentityLinksForTaskCmd(String taskId) {\n        this.taskId = taskId;\n    }\n\n    @SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n    @Override\n    public List<IdentityLink> execute(CommandContext commandContext) {\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n        \n        if (task == null) {\n            throw new FlowableObjectNotFoundException(\"task not found\");\n        }\n\n        List<IdentityLink> identityLinks = (List) task.getIdentityLinks();\n\n        // assignee is not part of identity links in the db.\n        // so if there is one, we add it here.\n        // @Tom: we discussed this long on skype and you agreed ;-)\n        // an assignee *is* an identityLink, and so must it be reflected in the API\n        //\n        // Note: we cant move this code to the TaskEntity (which would be cleaner),\n        // since the task.delete cascaded to all associated identityLinks\n        // and of course this leads to exception while trying to delete a non-existing identityLink\n        if (task.getAssignee() != null) {\n            IdentityLinkEntity identityLink = processEngineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService().createIdentityLink();\n            identityLink.setUserId(task.getAssignee());\n            identityLink.setType(IdentityLinkType.ASSIGNEE);\n            identityLink.setTaskId(task.getId());\n            identityLinks.add(identityLink);","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetIdentityLinksForTaskCmd.java#L30-L66","documentation":"GetIdentityLinksForTaskCmd.execute loads the TaskEntity via TaskService.getTask(taskId) and throws FlowableObjectNotFoundException with the terse message 'task not found' when it is null. Identity links (candidate users/groups) live on the task, so a nonexistent task cannot be queried. Note the message does not include the taskId, which makes diagnosing harder.","triggerScenarios":"Calling TaskService.getIdentityLinksForTask(taskId) with a taskId not present in ACT_RU_TASK — task already completed/deleted, id typo, or id from another database/history-only record.","commonSituations":"User clicks a stale link to a task completed moments earlier; job processed the task between fetch and this call; passing a historic task id to the runtime TaskService; cluster setups where a different DB is hit than expected.","solutions":["Check existence first: taskService.createTaskQuery().taskId(taskId).singleResult()","If the task was completed, query historyService.createHistoricTaskInstanceQuery().taskId(id) and use history identity-link APIs","Re-fetch the task id from the process variables/query instead of caching stale ids in the UI","Confirm the datasource points at the same database the task id came from","Catch FlowableObjectNotFoundException around the call and show a 'task no longer available' message"],"exampleFix":"// before\nList<IdentityLink> links = taskService.getIdentityLinksForTask(taskId);\n// after\nTask task = taskService.createTaskQuery().taskId(taskId).singleResult();\nList<IdentityLink> links = (task != null)\n    ? taskService.getIdentityLinksForTask(taskId)\n    : Collections.emptyList();","handlingStrategy":"try-catch","validationCode":"Task task = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (task == null) { /* completed/absent: fall back to history API */ }","typeGuard":null,"tryCatchPattern":"try {\n  List<IdentityLink> links = taskService.getIdentityLinksForTask(taskId);\n} catch (FlowableObjectNotFoundException e) {\n  logger.warn(\"Task {} no longer exists (may be completed)\", taskId);\n  links = Collections.emptyList();\n}","preventionTips":["Re-check task existence before each identity-link operation on user-facing flows","Use historic task queries when tasks may already be completed","Don't pass historic task ids to runtime TaskService APIs","Log the taskId in your own wrapper since this error message omits it"],"tags":["flowable","task","not-found","identity-link"],"backgroundTag":"record-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"}