{"record":{"id":"748d639fcf70dc5c","repo":"flowable/flowable-engine","slug":"form-with-formkey-formkey-does-not-exist-748d63","errorCode":null,"errorMessage":"Form with formKey '${formKey}' does not exist","messagePattern":"Form with formKey '(.+?)' does not exist","errorType":"exception","errorClass":"ActivitiObjectNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/form/JuelFormEngine.java","lineNumber":66,"sourceCode":"        if (taskForm.getFormKey() == null) {\n            return null;\n        }\n        String formTemplateString = getFormTemplateString(taskForm, taskForm.getFormKey());\n        ScriptingEngines scriptingEngines = Context.getProcessEngineConfiguration().getScriptingEngines();\n        TaskEntity task = (TaskEntity) taskForm.getTask();\n        return scriptingEngines.evaluate(formTemplateString, ScriptingEngines.DEFAULT_SCRIPTING_LANGUAGE, task.getExecution());\n    }\n\n    protected String getFormTemplateString(FormData formInstance, String formKey) {\n        String deploymentId = formInstance.getDeploymentId();\n\n        ResourceEntity resourceStream = Context\n                .getCommandContext()\n                .getResourceEntityManager()\n                .findResourceByDeploymentIdAndResourceName(deploymentId, formKey);\n\n        if (resourceStream == null) {\n            throw new ActivitiObjectNotFoundException(\"Form with formKey '\" + formKey + \"' does not exist\", String.class);\n        }\n\n        return new String(resourceStream.getBytes(), StandardCharsets.UTF_8);\n    }\n}\n","sourceCodeStart":48,"sourceCodeEnd":72,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/form/JuelFormEngine.java#L48-L72","documentation":"JuelFormEngine.getFormTemplateString looks up a deployment resource whose name equals the formKey. When no resource with that name exists in the deployment, it throws ActivitiObjectNotFoundException. The JUEL form engine resolves forms as deployment resources, so the formKey must exactly match a resource name.","triggerScenarios":"Rendering a task form via FormService.getRenderedTaskForm(formKey) / getRenderedStartForm where formKey points to a resource name that is not in the process definition's deployment.","commonSituations":"Form template file forgotten from the deployment bar; formKey typo or path mismatch (e.g. 'forms/approval.form' vs 'approval.form'); form deployed in a different deployment than the process definition; case-sensitive name mismatch.","solutions":["Add the form resource (matching the formKey exactly) to the process deployment","Correct the formKey in the BPMN XML to match the deployed resource name including path and case","Deploy the form in the same deployment as the process definition or verify the deploymentId used for lookup"],"exampleFix":"// before (BPMN)\n<startFormKey>forms/approve.form</startFormKey>  // not deployed\n// after: add forms/approve.form to the deployment repository\nrepositoryService.createDeployment().addClasspathResource(\"forms/approve.form\").addClasspathResource(\"process.bpmn20.xml\").deploy();","handlingStrategy":"validation","validationCode":"ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult();\nResource r = repositoryService.createDeploymentQuery().deploymentId(pd.getDeploymentId()).singleResult() != null ? null : null;\nboolean formExists = repositoryService.getResourceAsStream(pd.getDeploymentId(), formKey) != null; // throws if missing\n","typeGuard":"boolean formResourceExists(DeploymentBuilder b, String formKey) {\n    return ((DeploymentBuilderImpl) b).getResources().keySet().contains(formKey);\n}","tryCatchPattern":"try {\n    Object form = formService.getRenderedTaskForm(taskId);\n} catch (FlowableObjectNotFoundException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"does not exist\")) { /* fall back to default form */ }\n    else throw e;\n}","preventionTips":["Deploy the form template in the same deployment as the BPMN","Keep formKey strings in sync with resource paths (path + case-sensitive)","Verify resources with repositoryService.getResourceAsStream after deployment"],"tags":["forms","resource-not-found","deployment"],"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-18T11:17:12.947Z"}