passbolt/passbolt_api · error · BadRequestException
The transfer id is not valid.
Error message
The transfer id is not valid.
What it means
A 400 BadRequestException thrown in the public (unauthenticated) transfer view endpoint when the `id` path parameter is not a valid UUID. The TransfersViewController validates the transfer id format before attempting any database lookup, failing fast on malformed identifiers.
Solutions
- Ensure the client uses the UUID `id` field returned by the transfer-creation response
- Validate the id with a UUID regex on the client before calling the endpoint
- Check for undefined/null template variables interpolated into the URL
- If migrating from older clients, re-create the transfer to get a valid UUID id
Example fix
// before
const url = `/mobile/transfers/${transfer?.id}`;
// after
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(transfer.id)) throw new Error('invalid transfer id');
const url = `/mobile/transfers/${transfer.id}`; Defensive patterns
Strategy: validation
Validate before calling
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!UUID_RE.test(id)) throw new Error(`invalid transfer id: ${id}`); Type guard
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); } Try / catch
try { return await getTransfer(id); } catch (e) { if (e.status === 400 && /transfer id is not valid/i.test(e.message)) { throw new InvalidTransferIdError(id); } throw e; } Prevention
- Store and pass the transfer id exactly as returned by the API
- Guard URLs with an isUuid check before requesting
- Avoid hand-editing or truncating ids in logs/tests
When it happens
Trigger: GET /mobile/transfers/<id> where <id> is not a UUID — e.g. empty string, numeric id, a slug, or a truncated/corrupted UUID from a mis-built URL.
Common situations: Client storing the transfer id in local storage and losing part of it; building the URL by string concatenation with an undefined variable; copying a non-UUID identifier from another system; old API versions that used non-UUID ids.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Could not validate the transfer data.
- Could not validate the transfer data.
- Invalid id
- Please provide a valid request id.
- The authentication token id is invalid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/49caa388469f8818.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Mobile/src/Controller/Transfers/TransfersViewController.php:58
*/
public function initialize(): void
{
parent::initialize();
$this->Transfers = $this->fetchTable('Passbolt/Mobile.Transfers');
}
/**
* View a transfer status
*
* @param string $id transfer uuid
* @throws \Cake\Datasource\Exception\RecordNotFoundException if transfer does not exist
* @return void
*/
public function view(string $id): void
{
// Check request sanity
if (!Validation::uuid($id)) {
throw new BadRequestException(__('The transfer id is not valid.'));
}
// Contain options
$whitelist = ['contain' => ['user', 'user.profile']];
$options = $this->QueryString->get($whitelist);
$contain = empty($options['contain']['user']) ? [] : ['Users'];
$contain = empty($options['contain']['user.profile']) ? $contain : [
'Users.Profiles' => AvatarsTable::addContainAvatar(),
];
$transfer = $this->Transfers->find()
->contain($contain)
->where([
$this->Transfers->aliasField('id') => $id,
$this->Transfers->aliasField('user_id') => $this->User->id(),
])
->firstOrFail();
View on GitHub (pinned to 31c1bbc10f)