{"record":{"id":"3a30748c89a246ff","repo":"flowable/flowable-engine","slug":"either-casedefinitionid-or-casedefinitionkey-is-re","errorCode":null,"errorMessage":"Either caseDefinitionId or caseDefinitionKey is required.","messagePattern":"Either caseDefinitionId or caseDefinitionKey is required\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceCollectionResource.java","lineNumber":332,"sourceCode":"    @ApiOperation(value = \"Start a case instance\", tags = { \"Case Instances\" },\n            notes = \"Note that also a *transientVariables* property is accepted as part of this json, that follows the same structure as the *variables* property.\\n\\n\"\n            + \"Only one of *caseDefinitionId* or *caseDefinitionKey* an be used in the request body.\\n\\n\"\n            + \"Parameters *businessKey*, *variables* and *tenantId* are optional.\\n\\n\"\n            + \"If tenantId is omitted, the default tenant will be used.\\n\\n \"\n            + \"It is possible to send variables, transientVariables and startFormVariables in one request.\\n\\n\"\n            + \"More information about the variable format can be found in the REST variables section.\\n\\n \"\n            + \"Note that the variable-scope that is supplied is ignored, case-variables are always local.\\n\\n\",\n            code = 201)\n    @ApiResponses(value = {\n            @ApiResponse(code = 201, message = \"Indicates the case instance was created.\"),\n            @ApiResponse(code = 400, message = \"Indicates either the case definition was not found (based on id or key), no process is started by sending the given message or an invalid variable has been passed. Status description contains additional information about the error.\")\n    })\n    @PostMapping(value = \"/cmmn-runtime/case-instances\", produces = \"application/json\")\n    @ResponseStatus(HttpStatus.CREATED)\n    public CaseInstanceResponse createCaseInstance(@RequestBody CaseInstanceCreateRequest request) {\n\n        if (request.getCaseDefinitionId() == null && request.getCaseDefinitionKey() == null) {\n            throw new FlowableIllegalArgumentException(\"Either caseDefinitionId or caseDefinitionKey is required.\");\n        }\n\n        int paramsSet = ((request.getCaseDefinitionId() != null) ? 1 : 0) + ((request.getCaseDefinitionKey() != null) ? 1 : 0);\n\n        if (paramsSet > 1) {\n            throw new FlowableIllegalArgumentException(\"Only one of caseDefinitionId or caseDefinitionKey should be set.\");\n        }\n\n        if (request.isTenantSet()) {\n            // Tenant-id can only be used with either key or message\n            if (request.getCaseDefinitionId() != null) {\n                throw new FlowableIllegalArgumentException(\"TenantId can only be used with either caseDefinitionKey.\");\n            }\n        }\n\n        Map<String, Object> startVariables = null;\n        Map<String, Object> transientVariables = null;\n        Map<String, Object> startFormVariables = null;","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceCollectionResource.java#L314-L350","documentation":"createCaseInstance in the CMMN REST API requires the request body to identify which case definition to start. If neither caseDefinitionId nor caseDefinitionKey is set in CaseInstanceCreateRequest, it throws FlowableIllegalArgumentException (HTTP 400) because there is no way to resolve the definition.","triggerScenarios":"POST /cmmn-runtime/case-instances with a JSON body that omits both caseDefinitionId and caseDefinitionKey (e.g. body contains only variables, tenantId, or is effectively empty).","commonSituations":"Hand-written JSON payloads missing the definition fields, client DTO mapping bugs where the field is not serialized (wrong property name, null after mapping), copying request templates from other Flowable APIs that use different field names.","solutions":["Add caseDefinitionKey (e.g. \"caseDefinitionKey\":\"myCase\") to the request body — the usual choice","Or add caseDefinitionId if you have the deployed definition's id","Verify the client DTO actually serializes the field (correct getter/property name, non-null value)","Check the request body's Content-Type is application/json so the fields bind correctly"],"exampleFix":"// before\n{\"variables\": [{\"name\":\"a\",\"value\":1}]}\n// after\n{\"caseDefinitionKey\":\"myCase\", \"variables\": [{\"name\":\"a\",\"value\":1}]}","handlingStrategy":"validation","validationCode":"if (request.getCaseDefinitionId() == null && request.getCaseDefinitionKey() == null) {\n    throw new IllegalArgumentException(\"Set caseDefinitionId or caseDefinitionKey before starting a case instance\");\n}","typeGuard":"null","tryCatchPattern":"try {\n    startCase(request);\n} catch (HttpClientErrorException.BadRequest e) {\n    if (e.getResponseBodyAsString().contains(\"Either caseDefinitionId or caseDefinitionKey is required\")) {\n        log.error(\"Case start request missing definition reference\");\n    }\n}","preventionTips":["Always include caseDefinitionKey in start-request templates","Verify client DTO field names match the API contract","Unit-test request payload serialization before calling the API"],"tags":["rest","validation","required-field","cmmn"],"backgroundTag":"missing-required-argument","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"}