toeverything/AFFiNE · error · AuthenticationRequired
authentication_required
authentication_required
Error message
You must sign in first to access this resource.
What it means
Thrown by `AuthGuard.canActivate` for a non-`@Public`, non-`@Internal` endpoint when `signIn` resolved to no session (no cookie, no JWT, or both invalid/absent). HTTP 401. This is the primary 'not logged in' gate for the whole HTTP API.
Source
Thrown at packages/backend/server/src/core/auth/guard.ts:115
}
}
throw new AccessDenied('Invalid internal request');
}
// api is public
const isPublic = this.reflector.getAllAndOverride<boolean>(
PUBLIC_ENTRYPOINT_SYMBOL,
[clazz, handler]
);
const authedUser = await this.signIn(req, res, isPublic);
if (isPublic) {
return true;
}
if (!authedUser) {
throw new AuthenticationRequired();
}
return true;
}
async signIn(
req: Request,
res?: Response,
isPublic = false
): Promise<Session | null> {
const result = await this.resolveRequestSession(req, res, isPublic);
return result?.session ?? null;
}
private async resolveRequestSession(
req: Request,
res?: Response,
isPublic = falseView on GitHub (pinned to 26c515e050)
Solutions
- Authenticate first (sign in / refresh) and reissue the request with the resulting cookie or Bearer token.
- Ensure cookies are sent (`credentials: 'include'`) and the SameSite policy permits them.
- For native clients, refresh the access token via `/session/refresh` when it expires.
Example fix
// before
fetch('/api/auth/methods'); // 401
// after
fetch('/api/auth/methods', { credentials: 'include' });
// or
fetch('/api/auth/methods', {
headers: { authorization: `Bearer ${accessToken}` },
}); Defensive patterns
Strategy: validation
Validate before calling
async function ensureAuthed(): Promise<void> {
const r = await fetch('/api/auth/session', { credentials: 'include' });
if (r.status === 401) location.href = '/sign-in';
}
await ensureAuthed();
await fetch(protectedUrl, { credentials: 'include' }); Try / catch
try {
await fetch(protectedUrl, { credentials: 'include' });
} catch (e) {
// network error; not auth
}
// HTTP 401 handling
if (res.status === 401) { redirectToLogin(); } Prevention
- Check the session before calling protected endpoints.
- Send `credentials: 'include'` (browser) or a valid Bearer token (native).
- Intercept 401 globally and refresh/re-authenticate once before failing.
When it happens
Trigger: Calling any protected route without a session cookie or Bearer JWT, with an expired cookie session that `getUserSessionFromRequest` could not revive, or with a non-JWT Authorization header that `extractTokenFromHeader` rejected.
Common situations: Session expired and the refresh path did not run, the client forgot `credentials: 'include'`, a script/bot hit a protected URL, or a native client used an expired access token without refreshing.
Related errors
- authentication_required
- auth_session_expired
- The refresh token is invalid. | The auth session has expired
- auth_session_temporarily_unavailable
- action_forbidden
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/4a03edc4a6d9032e.
Report an issue: GitHub.