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

  1. Ensure the client uses the UUID `id` field returned by the transfer-creation response
  2. Validate the id with a UUID regex on the client before calling the endpoint
  3. Check for undefined/null template variables interpolated into the URL
  4. 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

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


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)