{"record":{"id":"945bbab932c420e8","repo":"flowable/flowable-engine","slug":"task-has-no-form-defined-945bba","errorCode":null,"errorMessage":"Task has no form defined","messagePattern":"Task has no form defined","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/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\" }, nickname = \"getHistoricTaskForm\")\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 = \"/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-rest/src/main/java/org/flowable/rest/service/api/history/HistoricTaskInstanceResource.java#L76-L106","documentation":"getTaskForm in HistoricTaskInstanceResource looks up the historic task instance, and if its formKey is empty/null it throws this FlowableIllegalArgumentException instead of returning a form. A historic task without a stored form key has no form definition to render, so the endpoint refuses to proceed.","triggerScenarios":"GET /history/historic-task-instances/{taskId}/form for a task that was completed without a form key, or whose form key was never set at task creation.","commonSituations":"Tasks created programmatically (no formKey); tasks from definitions without forms; querying forms for deleted/stale historic rows; clients assuming every historic task has a form.","solutions":["Check the historic task's formKey (GET .../historic-task-instances/{taskId}) before requesting the form.","Set a form key on the task/definition if the form should exist (taskService.setFormKey or in the BPMN userTask definition).","Handle FlowableIllegalArgumentException with HTTP 409/400 semantics client-side and show 'no form available'."],"exampleFix":"// before\nString form = get(\"/history/historic-task-instances/\" + taskId + \"/form\");\n// after\nHistoricTaskInstance t = get(\".../historic-task-instances/\" + taskId);\nif (t.getFormKey() == null || t.getFormKey().isEmpty()) return null;\nString form = get(\".../historic-task-instances/\" + taskId + \"/form\");","handlingStrategy":"validation","validationCode":"const task = await get(`/history/historic-task-instances/${taskId}`);\nif (!task.formKey) throw new Error('Task has no form defined: ' + taskId);","typeGuard":"function hasForm(task) { return typeof task.formKey === 'string' && task.formKey.length > 0; }","tryCatchPattern":"try { return getForm(taskId) } catch (e) { if (String(e.message) === 'Task has no form defined') return null; throw e }","preventionTips":["Fetch the historic task and check formKey before requesting its form","Set form keys on task definitions when forms are expected","Treat missing form as a normal business case, not an outage"],"tags":["rest-api","form","history-query","missing-form-key"],"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-14T11:17:12.474Z"}