{"record":{"id":"800394cecaef75ea","repo":"BookStackApp/BookStack","slug":"token-of-id-entry-id-has-expired","errorCode":null,"errorMessage":"Token of id {$entry->id} has expired.","messagePattern":"Token of id (.+?) has expired\\.","errorType":"exception","errorClass":"UserTokenExpiredException","httpStatus":null,"severity":"error","filePath":"app/Access/UserTokenService.php","lineNumber":50,"sourceCode":"            ->delete();\n    }\n\n    /**\n     * Get the user id from a token, while checking the token exists and has not expired.\n     *\n     * @throws UserTokenNotFoundException\n     * @throws UserTokenExpiredException\n     */\n    public function checkTokenAndGetUserId(string $token): int\n    {\n        $entry = $this->getEntryByToken($token);\n\n        if (is_null($entry)) {\n            throw new UserTokenNotFoundException('Token \"' . $token . '\" not found');\n        }\n\n        if ($this->entryExpired($entry)) {\n            throw new UserTokenExpiredException(\"Token of id {$entry->id} has expired.\", $entry->user_id);\n        }\n\n        return $entry->user_id;\n    }\n\n    /**\n     * Creates a unique token within the email confirmation database.\n     */\n    protected function generateToken(): string\n    {\n        $token = Str::random(24);\n        while ($this->tokenExists($token)) {\n            $token = Str::random(25);\n        }\n\n        return $token;\n    }\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Access/UserTokenService.php#L32-L68","documentation":"UserTokenExpiredException raised by checkTokenAndGetUserId when the token row exists but entryExpired() determines the created_at timestamp is older than the service's expiry window (e.g. 336 hours for invites). Input at fault: a token whose lifetime has elapsed.","triggerScenarios":"Thrown at app/Access/UserTokenService.php:50 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Have the user request a new invite or password-reset link","If needed, admin can extend expiryTime in the token service or regenerate the token","Inform the user links are time-limited and must be used promptly"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}