{"record":{"id":"9422babadddfa678","repo":"flowable/flowable-engine","slug":"key-provided-in-request-body-doesn-t-match-the-key","errorCode":null,"errorMessage":"Key provided in request body doesn't match the key in the resource URL.","messagePattern":"Key provided in request body doesn't match the key in the resource URL\\.","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-idm-rest/src/main/java/org/flowable/idm/rest/service/api/group/GroupResource.java","lineNumber":71,"sourceCode":"    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the group was updated.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested group was not found.\"),\n            @ApiResponse(code = 409, message = \"Indicates the requested group was updated simultaneously.\")\n    })\n    @PutMapping(value = \"/groups/{groupId}\", produces = \"application/json\")\n    public GroupResponse updateGroup(@ApiParam(name = \"groupId\") @PathVariable String groupId, @RequestBody GroupRequest groupRequest) {\n        Group group = getGroupFromRequest(groupId);\n\n        if (groupRequest.getId() == null || groupRequest.getId().equals(group.getId())) {\n            if (groupRequest.isNameChanged()) {\n                group.setName(groupRequest.getName());\n            }\n            if (groupRequest.isTypeChanged()) {\n                group.setType(groupRequest.getType());\n            }\n            identityService.saveGroup(group);\n        } else {\n            throw new FlowableIllegalArgumentException(\"Key provided in request body doesn't match the key in the resource URL.\");\n        }\n\n        return restResponseFactory.createGroupResponse(group);\n    }\n\n    @ApiOperation(value = \"Delete a group\", tags = { \"Groups\" }, code = 204)\n    @ApiResponses(value = {\n            @ApiResponse(code = 204, message = \"Indicates the group was found and  has been deleted. Response-body is intentionally empty.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested group does not exist.\")\n    })\n    @DeleteMapping(\"/groups/{groupId}\")\n    @ResponseStatus(HttpStatus.NO_CONTENT)\n    public void deleteGroup(@ApiParam(name = \"groupId\") @PathVariable String groupId) {\n        Group group = getGroupFromRequest(groupId);\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteGroup(group);\n        }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-idm-rest/src/main/java/org/flowable/idm/rest/service/api/group/GroupResource.java#L53-L89","documentation":"FlowableIllegalArgumentException thrown by the REST group-update endpoint when the group key in the request body does not match the {groupId} in the URL. The REST API treats the URL key as authoritative; PUT is only allowed when both keys agree. This protects against accidentally retargeting a group to a different identity.","triggerScenarios":"PUT /flowable-idm-service/groups/{groupId} with a body whose 'groupId' (key) field is set to a different value than the URL path variable, or missing/null in a client that copies the wrong field.","commonSituations":"Client code reuses a serialized group object from another group; frontend form submits a stale or user-editable groupId field; API consumers confuse group 'id' with 'name' or 'type' fields; template-driven requests where the body key was never updated after changing the URL.","solutions":["Set the groupId field in the request body to exactly the same value as the {groupId} path variable","Remove the groupId field from the update body if the API version allows omitting it, so only URL key is used","Fix the client code that builds the URL from a different variable than the one placed in the body","Check for whitespace/case differences between the URL segment and body key"],"exampleFix":"// before\nPUT /groups/sales\n{\"groupId\":\"marketing\",\"name\":\"Sales\"}\n// after\nPUT /groups/sales\n{\"groupId\":\"sales\",\"name\":\"Sales\"}","handlingStrategy":"validation","validationCode":"// JS client check before PUT\nif (body.groupId !== groupIdInUrl) {\n  body.groupId = groupIdInUrl; // URL key is authoritative\n}\nawait fetch(`/groups/${encodeURIComponent(groupIdInUrl)}`, {method:'PUT', body: JSON.stringify(body)});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always derive the body groupId from the same variable used to build the URL","Never let users edit the groupId field in update forms","Strip immutable fields (groupId) from update payloads"],"tags":["rest-api","request-validation","key-mismatch","flowable"],"backgroundTag":"invalid-argument-value","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"}