{"record":{"id":"0f6b2c78edf28546","repo":"passbolt/passbolt_api","slug":"the-authentication-token-is-missing","errorCode":null,"errorMessage":"The authentication token is missing.","messagePattern":"The authentication token is missing\\.","errorType":"http","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"plugins/PassboltCe/Mobile/src/Service/Transfers/TransfersUpdateService.php","lineNumber":164,"sourceCode":"    }\n\n    /**\n     * Check if operation is allowed\n     *\n     * @param \\Passbolt\\Mobile\\Model\\Entity\\Transfer $transfer entity\n     * @param \\App\\Utility\\UserAccessControl $uac user access control object\n     * @throws \\Cake\\Http\\Exception\\ForbiddenException if operation is not allowed for example:\n     * - Transfer or AuthToken is for another user\n     * - Authentication token is expired\n     * @return void\n     */\n    private function assertOperationIsAllowed(Transfer $transfer, UserAccessControl $uac): void\n    {\n        if ($transfer->user_id !== $uac->getId()) {\n            throw new ForbiddenException(__('This operation is not allowed for this user.'));\n        }\n        if (!isset($transfer->authentication_token)) {\n            throw new ForbiddenException(__('The authentication token is missing.'));\n        }\n        if ($transfer->authentication_token->user_id !== $uac->getId()) {\n            throw new ForbiddenException(__('The authentication token is not valid for this user.'));\n        }\n        if ($transfer->authentication_token->type !== AuthenticationToken::TYPE_MOBILE_TRANSFER) {\n            throw new ForbiddenException(__('The authentication token type is invalid.'));\n        }\n        if ($transfer->authentication_token->active !== true) {\n            throw new ForbiddenException(__('The authentication token is not active.'));\n        }\n        if ($transfer->authentication_token->isExpired()) {\n            throw new ForbiddenException(__('The authentication token is expired.'));\n        }\n    }\n\n    /**\n     * Return an updated transfer entity.\n     *","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Mobile/src/Service/Transfers/TransfersUpdateService.php#L146-L182","documentation":"Thrown by TransfersUpdateService::assertOperationIsAllowed when the loaded transfer has no associated authentication token entity. A mobile transfer must carry an active TYPE_MOBILE_TRANSFER authentication token to authorize page uploads.","triggerScenarios":"Updating a transfer whose authentication_token relation is unset — typically because the token was deleted/consumed, the transfer was created outside the mobile-transfer flow, or the token association failed to load.","commonSituations":"Token deleted by a cleanup task or by completing another transfer; reusing a transfer after its token was deactivated; client skipping the transfer-create step that generates the token.","solutions":["Restart the mobile transfer flow: create a new authentication token (mobile-transfer type) and a new transfer","Check the authentication_tokens table for an active token linked to the transfer's user","Do not reuse transfers across sessions; tokens are single-flow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const token = transfer.authenticationToken;\nif (!token) {\n  // token missing: restart transfer setup to obtain one\n  await startMobileTransferFlow();\n}","typeGuard":"function hasAuthToken(t) {\n  return t != null && typeof t === 'object' && 'id' in t.authenticationToken && t.authenticationToken != null;\n}","tryCatchPattern":"try {\n  await api.updateTransfer(transferId, payload);\n} catch (e) {\n  if (e.code === 403 && e.message.includes('authentication token is missing')) {\n    await restartTransferSetup();\n  }\n}","preventionTips":["Always run the create-transfer step which provisions the token","Persist the token with the transfer and verify presence before each update","Check for token cleanup jobs that may delete it mid-flow"],"tags":["mobile","transfer","authentication-token","forbidden"],"backgroundTag":"missing-credentials","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"}