{"record":{"id":"49caa388469f8818","repo":"passbolt/passbolt_api","slug":"the-transfer-id-is-not-valid-transfersviewcontroller","errorCode":null,"errorMessage":"The transfer id is not valid.","messagePattern":"The transfer id is not valid\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/Mobile/src/Controller/Transfers/TransfersViewController.php","lineNumber":58,"sourceCode":"     */\n    public function initialize(): void\n    {\n        parent::initialize();\n        $this->Transfers = $this->fetchTable('Passbolt/Mobile.Transfers');\n    }\n\n    /**\n     * View a transfer status\n     *\n     * @param string $id transfer uuid\n     * @throws \\Cake\\Datasource\\Exception\\RecordNotFoundException if transfer does not exist\n     * @return void\n     */\n    public function view(string $id): void\n    {\n        // Check request sanity\n        if (!Validation::uuid($id)) {\n            throw new BadRequestException(__('The transfer id is not valid.'));\n        }\n\n        // Contain options\n        $whitelist = ['contain' => ['user', 'user.profile']];\n        $options = $this->QueryString->get($whitelist);\n        $contain = empty($options['contain']['user']) ? [] : ['Users'];\n        $contain = empty($options['contain']['user.profile']) ? $contain : [\n            'Users.Profiles' => AvatarsTable::addContainAvatar(),\n        ];\n\n        $transfer = $this->Transfers->find()\n            ->contain($contain)\n            ->where([\n                $this->Transfers->aliasField('id') => $id,\n                $this->Transfers->aliasField('user_id') => $this->User->id(),\n            ])\n            ->firstOrFail();\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Mobile/src/Controller/Transfers/TransfersViewController.php#L40-L76","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst url = `/mobile/transfers/${transfer?.id}`;\n// after\nif (!/^[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');\nconst url = `/mobile/transfers/${transfer.id}`;","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(id)) throw new Error(`invalid transfer id: ${id}`);","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 { 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; }","preventionTips":["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"],"tags":["validation","uuid","mobile","transfers","bad-request"],"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"}