{"record":{"id":"58262000911bc3c3","repo":"passbolt/passbolt_api","slug":"the-authentication-token-does-not-exist-or-has-been-deleted-582620","errorCode":null,"errorMessage":"The authentication token does not exist or has been deleted.","messagePattern":"The authentication token does not exist or has been deleted\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/SsoRecover/src/Controller/Google/GoogleRecoverSuccessController.php","lineNumber":56,"sourceCode":"    }\n\n    /**\n     * @return void\n     * @throws \\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException\n     */\n    public function ssoRecoverSuccess(): void\n    {\n        if ($this->request->is('json')) {\n            throw new BadRequestException(__('Ajax/Json request not supported.'));\n        }\n\n        $this->User->assertNotLoggedIn();\n        $token = $this->getTokenFromUrlQuery();\n\n        try {\n            (new SsoAuthenticationTokenGetService())->getActiveNotExpiredOrFail($token, SsoState::TYPE_SSO_RECOVER);\n        } catch (RecordNotFoundException $e) {\n            throw new BadRequestException(\n                __('The authentication token does not exist or has been deleted.'),\n                null,\n                $e\n            );\n        } catch (CustomValidationException $e) {\n            throw new BadRequestException(\n                __('The authentication token has been expired.'),\n                null,\n                $e\n            );\n        }\n\n        $this->viewBuilder()\n            ->setTheme('Passbolt/Sso')\n            ->setLayout('default')\n            ->setTemplatePath('success')\n            ->setTemplate('stage3');\n    }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/SsoRecover/src/Controller/Google/GoogleRecoverSuccessController.php#L38-L74","documentation":"Thrown when the SSO_RECOVER authentication token from the URL query is not found as an active token; getActiveNotExpiredOrFail raised RecordNotFoundException and the controller wraps it in this BadRequestException. Tokens are single-use, so a missing token usually means it was already consumed or never existed.","triggerScenarios":"GET /sso/recover/success/google?token=... with a token value matching no record: token consumed by a prior success call, deleted, typo/truncation, or issued by a different instance/database.","commonSituations":"Refreshing or double-clicking the success URL (second request finds the token already used), replaying an old Google recovery link, switching environments mid-flow.","solutions":["Restart the SSO recovery flow to receive a fresh token and use the new link exactly once.","Verify the token parameter is complete and unaltered (URL-encoding, email client truncation).","Confirm the request targets the same passbolt instance that issued the token.","Avoid refreshing/re-submitting the success page; the token is consumed on first successful use."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const token = new URL(location.href).searchParams.get('token');\nif (!token) throw new Error('Cannot complete Google SSO recovery: token query parameter missing.');","typeGuard":"function tokenLooksValid(url) {\n  const t = new URL(url).searchParams.get('token');\n  return typeof t === 'string' && t.length >= 16 && !/\\s/.test(t);\n}","tryCatchPattern":"try {\n  await completeGoogleSsoRecoverSuccess(token);\n} catch (e) {\n  if (e.message.includes('does not exist or has been deleted')) {\n    restartSsoRecoverFlow(); // single-use token gone: start over\n  }\n}","preventionTips":["Use each recovery link exactly once; a second request will always fail.","Do not refresh or bookmark the success URL.","Verify tokens are not truncated by email clients or redirect chains.","Keep the whole flow within the same instance/environment."],"tags":["sso","authentication-token","token-not-found","google"],"backgroundTag":"record-not-found","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"}