Mintplex-Labs/anything-llm · error

Public token is required to validate a temporary auth token.

Error message

Public token is required to validate a temporary auth token.

What it means

TemporaryAuthToken.validate(publicToken) requires the public token string; calling it with an empty or undefined value throws before any database access. The parameter defaults to '', so omitting the argument entirely also lands here.

Solutions

  1. Pass the full public token exactly as issued: TemporaryAuthToken.validate(token)
  2. Verify the param name matches on both client and server (?token= vs ?publicToken=)
  3. Check for presence before calling and return a 400 with a clear message
  4. Inspect email/link templates and any redirect rules that may drop the query string

Example fix

// before
TemporaryAuthToken.validate(req.query.publicToken); // undefined when client sends ?token=

// after
const publicToken = req.query.token ?? req.query.publicToken;
if (!publicToken) return res.status(400).json({ error: 'token is required' });
TemporaryAuthToken.validate(publicToken);
Defensive patterns

Strategy: validation

Validate before calling

const publicToken = req.query.token ?? req.query.publicToken;

if (typeof publicToken !== 'string' || publicToken.length === 0) {
  return res.status(400).json({ error: 'token is required' });
}

const { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);

Type guard

const isNonEmptyTokenString = (v) => typeof v === 'string' && v.trim().length > 0;

Try / catch

// validate() returns { sessionToken, token, error } instead of throwing on caught paths,
// so check the error field:
const { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);
if (error === 'Public token is required to validate a temporary auth token.') {
  return res.status(400).json({ error: 'Missing token in request' });
}

Prevention

When it happens

Trigger: A route handler reading req.params.token when the route defines a different param name; a client sending ?publicToken= while the server reads ?token= (or vice versa); middleware that strips or rewrites the query string before validation.

Common situations: Shareable magic-link login flows where the query param was renamed between versions; email templates rendering the link without the token after template changes; proxy or redirect rules dropping query strings.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@a145d4d87d (2026-08-18). Data as JSON: /api/errors/77dc0bfcc8e036bb. Report an issue: GitHub.

Appendix: source

Thrown at server/models/temporaryAuthToken.js:75

    await prisma.temporary_auth_tokens.deleteMany({
      where: { userId: Number(userId) },
    });
    return true;
  },

  /**
   * 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) {

View on GitHub (pinned to a145d4d87d)