passbolt/passbolt_api · error · BadRequestException
The user does not exist or is already active or is disabled.
Error message
The user does not exist or is already active or is disabled.
What it means
Thrown by UserGetService::getNotActiveNotDeletedNotDisabledOrFail when the user identified by the given UUID exists but is already active, has been deleted, or is disabled. The service guarantees it only returns a user who is inactive, not deleted, and not enabled, and deliberately returns the same opaque message for all failure modes to avoid leaking account state to unauthenticated callers.
Solutions
- Check the user's record in the users table (active, deleted, disabled columns) to see which of the three conditions is true.
- If the user is already active, skip the activation flow and use the normal login/recover endpoint instead.
- If the user is deleted, recover via account recovery or have an admin create/restore the user.
- If the user is disabled, an admin must re-enable the account (UsersAdminController / users table update) before the flow can proceed.
- Verify you are using the correct user ID — copy it from the admin UI or a fresh API lookup, not from an old email/link.
Example fix
// before: replaying activation for an already-activated user
POST /users/<id>.json // 400: The user does not exist or is already active or is disabled.
// after: check state first, branch accordingly
$user = $this->Users->get($userId);
if ($user->isActive()) {
return $this->redirectToRoute('login'); // already activated
} Defensive patterns
Strategy: try-catch
Validate before calling
const user = await fetch(`/users/${userId}.json`).then(r => r.json());
if (user.active || user.deleted || user.disabled) {
throw new Error('User is not in a pending/activatable state');
} Try / catch
try {
await activateUser(userId);
} catch (e) {
if (e.response?.status === 400 && /already active or is disabled/.test(e.response.body?.message)) {
// user already active -> redirect to login; deleted/disabled -> show admin-contact UI
}
} Prevention
- Only run activation/registration-completion flows for users known to be pending.
- Use fresh user IDs from an API lookup, not stale links or cached IDs.
- Treat this 400 as a state check, not a data error — branch on the user's current state.
When it happens
Trigger: Calling an endpoint that requires a pending (not-yet-activated) user, e.g. POST /users/{id} for activation/setup completion or account recovery initiation, with the ID of a user whose status is ACTIVE (1), whose deleted flag is true, or whose disabled flag is true.
Common situations: Re-submitting a registration/activation link after the user already completed setup; replaying an old activation request on a staging DB where the user was activated manually; targeting a user that an admin deleted or disabled; using a stale UUID after a database re-import.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The user does not exist or is not active or is disabled.
- Account recovery case must be a string.
- Account recovery reason not supported.
- An array of arrays is expected.
- Few fields are missing for the V5.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/da0831df4f1be0e9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Service/Users/UserGetService.php:90
}
return $userEntity;
}
/**
* Get a user by ID or throw relevant HTTP exceptions
*
* @param string $userId user id uuid
* @throws \Cake\Http\Exception\NotFoundException if the user could not be found
* @throws \Cake\Http\Exception\BadRequestException if the userId is not a valid uuid
* @throws \Cake\Http\Exception\BadRequestException if the is active or deleted or disabled
* @return \App\Model\Entity\User
*/
public function getNotActiveNotDeletedNotDisabledOrFail(string $userId): User
{
$userEntity = $this->getOrFail($userId);
if ($userEntity->isActive()) {
throw new BadRequestException(__('The user does not exist or is already active or is disabled.'));
}
if ($userEntity->isDeleted()) {
throw new BadRequestException(__('The user does not exist or is already active or is disabled.'));
}
if ($userEntity->isDisabled()) {
throw new BadRequestException(__('The user does not exist or is already active or is disabled.'));
}
return $userEntity;
}
/**
* Get a user by ID or throw relevant HTTP exceptions
*
* @param string $userId user id uuid
* @throws \Cake\Http\Exception\NotFoundException if the user could not be found
* @throws \Cake\Http\Exception\BadRequestException if the userId is not a valid uuid
* @throws \Cake\Http\Exception\BadRequestException if the is not active or deleted or disabledView on GitHub (pinned to 31c1bbc10f)