{"record":{"id":"77dc0bfcc8e036bb","repo":"Mintplex-Labs/anything-llm","slug":"public-token-is-required-to-validate-a-temporary-a","errorCode":null,"errorMessage":"Public token is required to validate a temporary auth token.","messagePattern":"Public token is required to validate a temporary auth token\\.","errorType":"exception","errorClass":null,"httpStatus":401,"severity":"error","filePath":"server/models/temporaryAuthToken.js","lineNumber":75,"sourceCode":"    await prisma.temporary_auth_tokens.deleteMany({\n      where: { userId: Number(userId) },\n    });\n    return true;\n  },\n\n  /**\n   * Validates a temporary auth token and returns the session token\n   * to be set in the browser localStorage for authentication.\n   * @param {string} publicToken - the token to validate against\n   * @returns {Promise<{sessionToken: string|null, token: import(\"@prisma/client\").temporary_auth_tokens & {user: import(\"@prisma/client\").users} | null, error: string | null}>}\n   */\n  validate: async function (publicToken = \"\") {\n    /** @type {import(\"@prisma/client\").temporary_auth_tokens & {user: import(\"@prisma/client\").users} | undefined | null} **/\n    let token;\n\n    try {\n      if (!publicToken)\n        throw new Error(\n          \"Public token is required to validate a temporary auth token.\"\n        );\n      token = await prisma.temporary_auth_tokens.findUnique({\n        where: { token: String(publicToken) },\n        include: { user: true },\n      });\n      if (!token) throw new Error(\"Invalid token.\");\n      if (token.expiresAt < new Date()) throw new Error(\"Token expired.\");\n      if (token.user.suspended) throw new Error(\"User account suspended.\");\n\n      // Create a new session token for the user valid for 30 days\n      const sessionToken = makeJWT(\n        { id: token.user.id, username: token.user.username },\n        process.env.JWT_EXPIRY\n      );\n\n      return { sessionToken, token, error: null };\n    } catch (error) {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/a145d4d87d086bdb31d50f9bf9cd9c46d311780c/server/models/temporaryAuthToken.js#L57-L93","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass the full public token exactly as issued: TemporaryAuthToken.validate(token)","Verify the param name matches on both client and server (?token= vs ?publicToken=)","Check for presence before calling and return a 400 with a clear message","Inspect email/link templates and any redirect rules that may drop the query string"],"exampleFix":"// before\nTemporaryAuthToken.validate(req.query.publicToken); // undefined when client sends ?token=\n\n// after\nconst publicToken = req.query.token ?? req.query.publicToken;\nif (!publicToken) return res.status(400).json({ error: 'token is required' });\nTemporaryAuthToken.validate(publicToken);","handlingStrategy":"validation","validationCode":"const publicToken = req.query.token ?? req.query.publicToken;\n\nif (typeof publicToken !== 'string' || publicToken.length === 0) {\n  return res.status(400).json({ error: 'token is required' });\n}\n\nconst { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);","typeGuard":"const isNonEmptyTokenString = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"// validate() returns { sessionToken, token, error } instead of throwing on caught paths,\n// so check the error field:\nconst { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);\nif (error === 'Public token is required to validate a temporary auth token.') {\n  return res.status(400).json({ error: 'Missing token in request' });\n}","preventionTips":["Name the query parameter identically in link templates, client code, and route handlers","Check link/email templates render the token fully after any template change","Watch for proxies or redirects that drop query strings before the validation route"],"tags":["auth","temporary-token","validation"],"backgroundTag":"missing-auth-token","analyzedSha":"a145d4d87d086bdb31d50f9bf9cd9c46d311780c","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}