{"record":{"id":"1c4c6c4fb777230f","repo":"flowable/flowable-engine","slug":"task-has-no-form-defined-1c4c6c","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-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskResource.java","lineNumber":188,"sourceCode":"            // Ignore delete-reason since the task-history (where the reason is\n            // recorded) will be deleted anyway\n            taskService.deleteTask(taskToDelete.getId(), cascadeHistory);\n        } else {\n            // Delete with delete-reason\n            taskService.deleteTask(taskToDelete.getId(), deleteReason);\n        }\n    }\n    \n    @ApiOperation(value = \"Get a task form\", tags = { \"Tasks\" })\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-runtime/tasks/{taskId}/form\", produces = \"application/json\")\n    public String getTaskForm(@ApiParam(name = \"taskId\") @PathVariable String taskId) {\n        Task task = getTaskFromRequest(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.convertTaskFormInfo(formInfo, task);\n        } else {\n            SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();\n            return restResponseFactory.getFormModelString(new FormModelResponse(formInfo, formModel));\n        }\n    }\n\n    protected void completeTask(Task task, TaskActionRequest actionRequest) {\n        TaskCompletionBuilder taskCompletionBuilder = taskService.createTaskCompletionBuilder();\n\n        if (actionRequest.getVariables() != null) {\n            for (RestVariable var : actionRequest.getVariables()) {\n                if (var.getName() == null) {\n                    throw new FlowableIllegalArgumentException(\"Variable name is required\");","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskResource.java#L170-L206","documentation":"GET /cmmn-runtime/tasks/{taskId}/form requires the task to have a form key defined; otherwise there is no form to return. The endpoint throws FlowableIllegalArgumentException (HTTP 400) when the task's formKey is empty and no form model can be fetched.","triggerScenarios":"Calling GET /cmmn-runtime/tasks/{taskId}/form for a task whose formKey was never set in the case model (human task without formKey attribute) or set to an empty string.","commonSituations":"Case diagrams where the human task element omits the form key; dynamic tasks created programmatically without a form key; clients assuming every task has a form.","solutions":["Set a formKey on the human task in the CMMN model and redeploy the case definition.","Use getTaskFormModel only after checking the task's formKey via GET /cmmn-runtime/tasks/{taskId} (formKey field).","If no form is needed, don't call the form endpoint; render your own UI.","Provide the form through a form-deployment referenced by the formKey so the model resolves."],"exampleFix":"// before\nGET /flowable-rest/cmmn-runtime/tasks/123/form  // 400 Task has no form defined\n\n// after: check first\nconst task = await get(`/cmmn-runtime/tasks/123`);\nif (task.formKey) { await get(`/cmmn-runtime/tasks/123/form`); }","handlingStrategy":"validation","validationCode":"const task = await api.get(`/cmmn-runtime/tasks/${id}`);\nif (!task.formKey) return null; // no form defined","typeGuard":null,"tryCatchPattern":"try { return await api.get(`/cmmn-runtime/tasks/${id}/form`); } catch (e) { if (e.response && e.response.status === 400) return null; throw e; }","preventionTips":["Always set a formKey on human tasks in the CMMN model","Check task.formKey before calling the form endpoint","Treat 400 on form fetch as 'no form' rather than a crash"],"tags":["rest-api","cmmn","form","missing-form-key"],"backgroundTag":"resource-not-found","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"}