Mintplex-Labs/anything-llm · error
Invalid token.
Error message
Invalid token.
What it means
validate() ran a findUnique on temporary_auth_tokens for the given token string and found no row. The token never existed in this database, was revoked or deleted, or belongs to a different instance. Note the token column is matched exactly - truncation or whitespace breaks the lookup.
Solutions
- Generate and share a fresh temporary auth token
- Copy the token completely and URL-decode it before validating
- Confirm the client and server hit the same database/instance
- If tokens are single-use by policy, treat consumption as expected and re-issue
Example fix
// before TemporaryAuthToken.validate(token.trimEnd() + '='); // accidental mutation -> Invalid token. // after TemporaryAuthToken.validate(decodeURIComponent(token).trim());
Defensive patterns
Strategy: try-catch
Validate before calling
const publicToken = decodeURIComponent(String(rawToken ?? '')).trim();
if (publicToken.length === 0) {
return res.status(400).json({ error: 'token is required' });
} Try / catch
const { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);
if (error === 'Invalid token.') {
// unknown/revoked token: respond 401 and offer to generate a new link
return res.status(401).json({ error: 'Invalid login link. Request a new one.' });
}
if (error) return res.status(401).json({ error }); Prevention
- URL-decode and trim tokens before validating so encoding artifacts do not break the exact match
- Point all instances at the same database so issued tokens are always findable
- Treat tokens as potentially consumed or revoked; always offer a re-issue path
When it happens
Trigger: A typo'd or truncated token (copy missing characters, URL-decoding issues); the token was deleted after use or by an admin; the database was reset while the link was still being shared; '+' or special characters mangled by query parsing.
Common situations: Magic-link emails clipped by mail clients; tokens copied with surrounding whitespace or percent-encoding intact; load-balanced instances pointing at different databases.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Public token is required to validate a temporary auth token.
- Token expired.
- Could not find a document by id
- Device not approved
- Device not found
AI-assisted analysis of Mintplex-Labs/anything-llm@a145d4d87d (2026-08-18).
Data as JSON: /api/errors/37c1e322b060a5f4.
Report an issue: GitHub.
Appendix: source
Thrown at server/models/temporaryAuthToken.js:82
* Validates a temporary auth token and returns the session token
* to be set in the browser localStorage for authentication.
* @param {string} publicToken - the token to validate against
* @returns {Promise<{sessionToken: string|null, token: import("@prisma/client").temporary_auth_tokens & {user: import("@prisma/client").users} | null, error: string | null}>}
*/
validate: async function (publicToken = "") {
/** @type {import("@prisma/client").temporary_auth_tokens & {user: import("@prisma/client").users} | undefined | null} **/
let token;
try {
if (!publicToken)
throw new Error(
"Public token is required to validate a temporary auth token."
);
token = await prisma.temporary_auth_tokens.findUnique({
where: { token: String(publicToken) },
include: { user: true },
});
if (!token) throw new Error("Invalid token.");
if (token.expiresAt < new Date()) throw new Error("Token expired.");
if (token.user.suspended) throw new Error("User account suspended.");
// Create a new session token for the user valid for 30 days
const sessionToken = makeJWT(
{ id: token.user.id, username: token.user.username },
process.env.JWT_EXPIRY
);
return { sessionToken, token, error: null };
} catch (error) {
console.error("FAILED TO VALIDATE TEMPORARY AUTH TOKEN.", error.message);
return { sessionToken: null, token: null, error: error.message };
} finally {
// Delete the token after it has been used under all circumstances if it was retrieved
if (token)
await prisma.temporary_auth_tokens.delete({ where: { id: token.id } });
}View on GitHub (pinned to a145d4d87d)