{"record":{"id":"1988db9c9bf728d6","repo":"flowable/flowable-engine","slug":"only-one-of-casedefinitionid-or-casedefinitionkey","errorCode":null,"errorMessage":"Only one of caseDefinitionId or caseDefinitionKey should be set.","messagePattern":"Only one of caseDefinitionId or caseDefinitionKey should be set\\.","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":338,"sourceCode":"            + \"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;\n        if (request.getStartFormVariables() != null) {\n            startFormVariables = new HashMap<>();\n            for (RestVariable variable : request.getStartFormVariables()) {\n                if (variable.getName() == null) {\n                    throw new FlowableIllegalArgumentException(\"Variable name is required.\");\n                }","sourceCodeStart":320,"sourceCodeEnd":356,"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#L320-L356","documentation":"createCaseInstance allows only one way of resolving the case definition. If the request sets both caseDefinitionId and caseDefinitionKey (more than one parameter set), Flowable throws FlowableIllegalArgumentException (HTTP 400) because the target definition would be ambiguous.","triggerScenarios":"POST /cmmn-runtime/case-instances with a body containing both caseDefinitionId and caseDefinitionKey (paramsSet > 1).","commonSituations":"Client code that always populates both fields from separate config values, template payloads copied between examples, generic start-form code that forwards all known definition fields.","solutions":["Remove caseDefinitionId and keep only caseDefinitionKey (preferred when targeting the latest version)","Or keep only caseDefinitionId when you must pin an exact deployed definition version","Fix the client mapping so it sets exactly one of the two fields","Validate the payload client-side before sending"],"exampleFix":"// before\n{\"caseDefinitionId\":\"myCase:1:4\", \"caseDefinitionKey\":\"myCase\"}\n// after\n{\"caseDefinitionKey\":\"myCase\"}","handlingStrategy":"validation","validationCode":"int set = (request.getCaseDefinitionId() != null ? 1 : 0) + (request.getCaseDefinitionKey() != null ? 1 : 0);\nif (set > 1) throw new IllegalArgumentException(\"Set only one of caseDefinitionId / caseDefinitionKey\");","typeGuard":"null","tryCatchPattern":"try {\n    startCase(request);\n} catch (HttpClientErrorException.BadRequest e) {\n    if (e.getResponseBodyAsString().contains(\"Only one of caseDefinitionId or caseDefinitionKey\")) {\n        request.setCaseDefinitionId(null); // keep key only and retry\n    }\n}","preventionTips":["Build start requests with exactly one definition reference","Clear the other field when one is set programmatically","Validate payloads with a schema before sending"],"tags":["rest","validation","ambiguous-parameters","cmmn"],"backgroundTag":"mutually-exclusive-options","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"}