{"record":{"id":"ce9cdc85a8c205ad","repo":"passbolt/passbolt_api","slug":"the-role-identifier-is-not-valid","errorCode":null,"errorMessage":"The role identifier is not valid.","messagePattern":"The role identifier is not valid\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Controller/Roles/RolesUpdateController.php","lineNumber":37,"sourceCode":"\nuse App\\Controller\\AppController;\nuse App\\Service\\Roles\\RolesUpdateService;\nuse Cake\\Http\\Exception\\BadRequestException;\nuse Cake\\Validation\\Validation;\n\nclass RolesUpdateController extends AppController\n{\n    /**\n     * @param string $roleId Role identifier to update.\n     * @return void\n     */\n    public function update(string $roleId): void\n    {\n        $this->assertJson();\n        $this->User->assertIsAdmin();\n\n        if (!Validation::uuid($roleId)) {\n            throw new BadRequestException(__('The role identifier is not valid.'));\n        }\n\n        $result = (new RolesUpdateService())->update(\n            $this->User->getAccessControl(),\n            $roleId,\n            $this->getRequest()->getData()\n        );\n\n        $this->success(__('The role was successfully updated.'), $result);\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":49,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Roles/RolesUpdateController.php#L19-L49","documentation":"Thrown by RolesUpdateController::update() when the roleId path parameter fails CakePHP's Validation::uuid() check before any service logic runs. It is a request-sanity guard: role updates are only addressable by a valid UUID, so a malformed identifier is rejected as a 400 Bad Request without touching the database.","triggerScenarios":"Calling PUT /roles/<id>.json where <id> is not a UUID v4 string — e.g. a role name like 'admin', a slug, a truncated id, or an empty segment.","commonSituations":"Client code passing role names instead of ids; hard-coded or copy-pasted ids with typos; older integrations built against an API that accepted names; string concatenation dropping part of the id.","solutions":["Validate the role id with a UUID check on the client before calling the endpoint","Look up the role id from the GET /roles.json listing instead of using a name or slug","Fix id construction/interpolation in the calling code (check for truncation or wrong variable)","Ensure the request targets PUT /roles/{uuid}.json with the id in the path, not the body"],"exampleFix":"// before\nawait api.put(`/roles/${roleName}.json`, data); // roleName = 'admin'\n// after\nconst roles = await api.get('/roles.json');\nconst role = roles.body.find(r => r.name === roleName);\nif (!isUuid(role.id)) throw new Error('invalid role id');\nawait api.put(`/roles/${role.id}.json`, data);","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nif (!UUID_RE.test(roleId)) throw new Error(`invalid role id: ${roleId}`);","typeGuard":"function isUuid(v) { return typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v); }","tryCatchPattern":"try { await api.put(`/roles/${roleId}.json`, data); }\ncatch (e) { if (e.response?.status === 400) { /* resolve id from /roles.json and retry */ } else throw e; }","preventionTips":["Always resolve role ids from the roles listing endpoint, never from names","Run ids through a UUID regex before any API call","Avoid string-concatenating ids; use template helpers that validate","Log the exact URL on 400s to spot truncated ids fast"],"tags":["validation","uuid","bad-request","cakephp"],"backgroundTag":"invalid-identifier-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}