{"record":{"id":"8b8b7f1530eececb","repo":"flowable/flowable-engine","slug":"task-has-no-form-defined","errorCode":null,"errorMessage":"Task has no form defined","messagePattern":"Task has no form defined","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"warning","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/task/HistoricTaskInstanceResource.java","lineNumber":94,"sourceCode":"        HistoricTaskInstance task = getHistoricTaskInstanceFromRequestWithoutAccessCheck(taskId);\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteHistoricTask(task);\n        }\n        \n        historyService.deleteHistoricTaskInstance(taskId);\n    }\n    \n    @ApiOperation(value = \"Get a historic task instance form\", tags = { \"History Task\" })\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates request was successful and the task form is returned\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested task was not found.\")\n    })\n    @GetMapping(value = \"/cmmn-history/historic-task-instances/{taskId}/form\", produces = \"application/json\")\n    public String getTaskForm(@ApiParam(name = \"taskId\") @PathVariable String taskId) {\n        HistoricTaskInstance task = getHistoricTaskInstanceFromRequest(taskId);\n        if (StringUtils.isEmpty(task.getFormKey())) {\n            throw new FlowableIllegalArgumentException(\"Task has no form defined\");\n        }\n        \n        FormInfo formInfo = taskService.getTaskFormModel(task.getId());\n        if (formHandlerRestApiInterceptor != null) {\n            return formHandlerRestApiInterceptor.convertHistoricTaskFormInfo(formInfo, task);\n        } else {\n            SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();\n            return restResponseFactory.getFormModelString(new FormModelResponse(formInfo, formModel));\n        }\n    }\n}\n","sourceCodeStart":76,"sourceCodeEnd":106,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/task/HistoricTaskInstanceResource.java#L76-L106","documentation":"FlowableIllegalArgumentException thrown by the historic task form endpoint when the historic task instance exists but its formKey is empty. The endpoint cannot return a form model for a task that was never associated with a form, so it rejects the request early. This typically means the task's form definition was not set (or not captured in history) when the task was created/completed.","triggerScenarios":"GET /cmmn-history/historic-task-instances/{taskId}/form for a task whose historic FormKey is null/empty — e.g. the task was created without a form, or formKey handling changed between Flowable versions so form keys are no longer stored on historic tasks.","commonSituations":"Tasks created programmatically (TaskService) with no form key; CMMN tasks whose form key was never set in the model; querying form for very old historic tasks after a Flowable upgrade changed form-key persistence; formProvider/flowable-form-engine not deployed so form keys were never resolved.","solutions":["Verify the task actually has a form key via GET /cmmn-history/historic-task-instances/{taskId} and checking the formKey field before calling the form endpoint","Set a form key on the task/CMMN case model so the historic task records one","If formKey exists but form info is needed, call taskService.getTaskFormModel yourself only after confirming a non-empty formKey","Check Flowable version for changes in form-key capture on historic tasks; upgrade/patch if form keys were previously stored"],"exampleFix":"// before\nString form = client.getFormForHistoricTask(taskId); // 500/400 when no form\n// after\nHistoricTaskInstance task = client.getHistoricTask(taskId);\nString form = (task.getFormKey() != null && !task.getFormKey().isEmpty())\n    ? client.getFormForHistoricTask(taskId) : null;","handlingStrategy":"validation","validationCode":"const task = await fetch(`/cmmn-history/historic-task-instances/${taskId}`).then(r => r.json());\nif (!task.formKey) return null; // no form defined, skip form fetch","typeGuard":"function hasForm(task) {\n  return task != null && typeof task.formKey === 'string' && task.formKey.length > 0;\n}","tryCatchPattern":"try {\n  return await fetchForm(taskId);\n} catch (e) {\n  if (String(e.message).includes('Task has no form defined')) return null;\n  throw e;\n}","preventionTips":["Check formKey on the historic task resource before requesting the form","Ensure tasks are created with a form key when forms are expected","Test form endpoints against tasks created programmatically without forms","Account for form-key persistence differences when upgrading Flowable versions"],"tags":["rest","forms","historical-data","flowable"],"backgroundTag":"empty-required-field","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"}