{"record":{"id":"decb9a892f4a2beb","repo":"flowable/flowable-engine","slug":"invalid-action-action-decb9a","errorCode":null,"errorMessage":"Invalid action: '${action}'.","messagePattern":"Invalid action: '(.+?)'\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":409,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceResource.java","lineNumber":111,"sourceCode":"        CaseInstance caseInstance = getCaseInstanceFromRequestWithoutAccessCheck(caseInstanceId);\n\n        if (StringUtils.isNotEmpty(updateRequest.getAction())) {\n\n            if (restApiInterceptor != null) {\n                restApiInterceptor.doCaseInstanceAction(caseInstance, updateRequest);\n            }\n\n            if (RestActionRequest.EVALUATE_CRITERIA.equals(updateRequest.getAction())) {\n                runtimeService.evaluateCriteria(caseInstance.getId());\n\n            } else if (CaseInstanceUpdateRequest.ACTION_CLAIM.equals(updateRequest.getAction())) {\n                runtimeService.claimCaseInstance(caseInstanceId, updateRequest.getAssignee());\n\n            } else if (CaseInstanceUpdateRequest.ACTION_UNCLAIM.equals(updateRequest.getAction())) {\n                runtimeService.unclaimCaseInstance(caseInstanceId);\n\n            } else {\n                throw new FlowableIllegalArgumentException(\"Invalid action: '\" + updateRequest.getAction() + \"'.\");\n            }\n\n        } else { // regular update\n\n            if (restApiInterceptor != null) {\n                restApiInterceptor.updateCaseInstance(caseInstance, updateRequest);\n            }\n\n            boolean hasUpdates = false;\n            CaseInstanceUpdateBuilder updateBuilder = runtimeService.createCaseInstanceUpdateBuilder(caseInstanceId);\n\n            if (updateRequest.getName() != null) {\n                updateBuilder.name(updateRequest.getName());\n                hasUpdates = true;\n            }\n            if (updateRequest.getBusinessKey() != null) {\n                updateBuilder.businessKey(updateRequest.getBusinessKey());\n                hasUpdates = true;","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceResource.java#L93-L129","documentation":"Thrown by updateCaseInstance (PUT on a case instance) when the 'action' field in the CaseInstanceUpdateRequest body is neither 'claim' nor 'unclaim'. Flowable only supports these two actions on this endpoint; anything else is rejected as an invalid argument via FlowableIllegalArgumentException.","triggerScenarios":"PUT /cmmn-runtime/case-instances/{caseInstanceId} with a JSON body whose 'action' property is an unsupported string (e.g. 'suspend', 'activate', 'complete', or a typo like 'claime'), while no assignee-based regular update path applies.","commonSituations":"Copy-pasting request bodies from the process (BPMN) REST API which supports more actions; typos or wrong casing in the action string; clients sending action values not valid for CMMN case instances; API version drift where an action existed in a different product/endpoint.","solutions":["Set 'action' to exactly \"claim\" or \"unclaim\" in the request body.","To claim, include the \"assignee\" field alongside action=claim; for unclaim, no assignee is needed.","Remove the 'action' field entirely if you intend a regular update handled by restApiInterceptor instead of a claim/unclaim.","Check the Flowable REST API docs for your version to confirm the supported action values."],"exampleFix":"// before\nPUT /cmmn-runtime/case-instances/case1\n{\"action\":\"activate\"}\n// after\nPUT /cmmn-runtime/case-instances/case1\n{\"action\":\"claim\",\"assignee\":\"johnDoe\"}","handlingStrategy":"validation","validationCode":"const VALID_ACTIONS = ['claim', 'unclaim'];\nif (body.action && !VALID_ACTIONS.includes(body.action)) {\n  throw new Error(`Invalid action '${body.action}'; use 'claim' or 'unclaim'`);\n}\nif (body.action === 'claim' && !body.assignee) {\n  throw new Error('claim requires an assignee');\n}","typeGuard":"function isCaseAction(a) {\n  return typeof a === 'string' && ['claim', 'unclaim'].includes(a);\n}","tryCatchPattern":"try {\n  await updateCaseInstance(caseId, body);\n} catch (e) {\n  if (e.status === 400) { /* invalid action: fix body before retry */ }\n  else throw e;\n}","preventionTips":["Use a constant/enum for action values instead of free-form strings.","Don't reuse BPMN process instance action bodies for CMMN case instances.","Validate the request body against the CaseInstanceUpdateRequest schema before sending."],"tags":["rest-api","invalid-action","validation","flowable"],"backgroundTag":"invalid-enum-value","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"}