BookStackApp/BookStack · error · NotFoundException
errors.login_user_not_found
Error message
errors.login_user_not_found
What it means
This NotFoundException is thrown by currentOrLastAttemptedUser() when there is no authenticated user and no user was stored from the last login attempt. The controller needs a user context (e.g. to render a user-specific page after a partial login) but both lookups came up empty. It guards against acting on a null user.
Source
Thrown at app/Access/Controllers/HandlesPartialLogins.php:20
namespace BookStack\Access\Controllers;
use BookStack\Access\LoginService;
use BookStack\Exceptions\NotFoundException;
use BookStack\Users\Models\User;
trait HandlesPartialLogins
{
/**
* @throws NotFoundException
*/
protected function currentOrLastAttemptedUser(): User
{
$loginService = app()->make(LoginService::class);
$user = auth()->user() ?? $loginService->getLastLoginAttemptUser();
if (!$user) {
throw new NotFoundException(trans('errors.login_user_not_found'));
}
return $user;
}
protected function clearLastAttemptedUser(): void
{
$loginService = app()->make(LoginService::class);
$loginService->clearLastLoginAttempted();
}
}
View on GitHub (pinned to 18f8469a1c)
Solutions
- Log in first (complete or attempt a login) so a user is present in session before hitting this route
- Check session configuration (SESSION_DRIVER, domain, secure settings) so the last-attempted user persists across requests
- If integrating, ensure the flow that redirects into this controller actually stores the attempted user via LoginService before redirecting
- Clear stale cookies and retry with a fresh session
Defensive patterns
Strategy: try-catch
Validate before calling
if (auth()->user() === null && \BookStack\Access\LoginService::getLastLoginAttemptUser() === null) {
redirect('/login')->send();
} Type guard
function hasLoginContext(): bool {
return auth()->user() instanceof \BookStack\Users\User;
} Try / catch
try {
$user = $controller->currentOrLastAttemptedUser();
} catch (\BookStack\Exceptions\NotFoundException $e) {
return redirect('/login')->with('error', $e->getMessage());
} Prevention
- Ensure routes using this trait are only reached from login/MFA flows that set the attempted user
- Keep session storage persistent and shared (database/redis) across servers
- Avoid long-lived links into partial-login pages; treat sessions as ephemeral
When it happens
Trigger: Calling a controller action that uses HandlesPartialLogins when auth()->user() returns null AND LoginService::getLastLoginAttemptUser() finds no session-stored 'last-login-attempt' user (session expired, cleared, or the method is called without a preceding failed login attempt).
Common situations: User hits a partial-login page (e.g. MFA/invite flow) directly via bookmark with an expired or missing session; sessions flushed after app cache clearing; load balancer routing to a different server losing session state; calling the endpoint without ever attempting login.
Related errors
- errors.social_no_action_defined
- Login not allowed for guest user
- auth.mfa_throttle
- errors.oidc_already_logged_in
- errors.saml_already_logged_in
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/f5dd3924879a1846.
Report an issue: GitHub.