passbolt/passbolt_api · error · CustomValidationException
The role could not be updated.
Error message
The role could not be updated.
What it means
RolesUpdateService::update throws this CustomValidationException when the edited role entity fails model validation during saveOrFail (PersistenceFailedException). The entity errors are embedded so the API consumer sees exactly which field was rejected.
Solutions
- Check the `errors` object in the 400 response for the failing field.
- Ensure the new role name is unique among existing roles (GET /roles).
- Send a non-empty name within the length limit.
- Retry PUT /roles/{id} with a corrected payload.
Example fix
// before
PUT /roles/<id> {"name": "editor"} // duplicate -> 400
// after
PUT /roles/<id> {"name": "editor-v2"} -> 200 Defensive patterns
Strategy: validation
Validate before calling
const existing = await api.listRoles();
function validRename(roleId, newName, existing) {
return typeof newName === 'string' && newName.trim().length > 0
&& newName.length <= 255
&& !existing.some(r => r.id !== roleId && r.name === newName);
}
// abort PUT if validRename(...) is false Type guard
function isRenamePayload(v) {
return typeof v === 'object' && v !== null && typeof v.name === 'string' && v.name.trim().length > 0;
} Try / catch
try {
await api.updateRole(roleId, { name });
} catch (e) {
if (e.status === 400 && e.body?.errors?.name) {
// duplicate or invalid name: prompt user for a different one
} else throw e;
} Prevention
- Check name uniqueness against GET /roles before renaming
- Require non-empty names and cap length at 255 chars
- Trim whitespace client-side before submitting
- Surface per-field errors from 400 responses in the UI
When it happens
Trigger: PUT /roles/{id} with a new name that violates Roles table rules: empty name, name longer than 255 characters, or uniqueness rule violation (renaming a role to an existing role's name).
Common situations: Renaming a role to a name that already exists, submitting a blank name from a UI that allowed empty input, or overly long names pasted from external sources.
Related errors
- The role could not be deleted.
- The role could not be saved.
- The role identifier is not valid.
- 400
- Could not delete the role, please try again later.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/adcefcc767ce2443.
Report an issue: GitHub.
Appendix: source
Thrown at src/Service/Roles/RolesUpdateService.php:68
* @param \App\Utility\UserAccessControl $uac UAC object.
* @param string $roleId Role identifier to update.
* @param array $data Data to save.
* @return \App\Model\Entity\Role
*/
public function update(UserAccessControl $uac, string $roleId, array $data): Role
{
$uac->assertIsAdmin();
$role = $this->getRole($roleId);
$oldName = $role->name;
$role = $this->patchRoleEntity($role, $data, $uac);
try {
$result = $this->Roles->saveOrFail($role);
} catch (PersistenceFailedException $e) { // @phpstan-ignore-line
$errors = $e->getEntity()->getErrors();
throw new CustomValidationException(
__('The role could not be updated.'),
$errors
);
} catch (Exception $e) {
throw new InternalErrorException(__('Could not update the role, please try again later.'), null, $e);
}
$this->dispatchEvent(self::AFTER_ROLE_UPDATE_SUCCESS_EVENT_NAME, [
'uac' => $uac,
'role' => $result,
'oldName' => $oldName,
]);
return $result;
}
/**
* @param string $roleId Role identifier to get.View on GitHub (pinned to 31c1bbc10f)