{"record":{"id":"62e4ba17f1b3cdc0","repo":"FlowiseAI/Flowise","slug":"unauthorized-62e4ba","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"packages/server/src/enterprise/middleware/passport/index.ts","lineNumber":237,"sourceCode":"                    return res.status(HttpStatusCode.Ok).json({ redirectUrl: '/organization-setup' })\n                default:\n                    return res.status(HttpStatusCode.Ok).json({ redirectUrl: '/organization-setup' })\n            }\n        }\n        switch (platform) {\n            case Platform.ENTERPRISE:\n                if (!identityManager.isLicenseValid()) {\n                    return res.status(HttpStatusCode.Ok).json({ redirectUrl: '/license-expired' })\n                }\n                return res.status(HttpStatusCode.Ok).json({ redirectUrl: '/signin' })\n            default:\n                return res.status(HttpStatusCode.Ok).json({ redirectUrl: '/signin' })\n        }\n    })\n\n    app.post('/api/v1/auth/refreshToken', async (req, res) => {\n        const refreshToken = req.cookies.refreshToken\n        if (!refreshToken) return res.sendStatus(401)\n\n        jwt.verify(refreshToken, getJWTRefreshTokenSecret(), async (err: any, payload: any) => {\n            if (err || !payload) return res.status(401).json({ message: ErrorMessage.REFRESH_TOKEN_EXPIRED })\n            // @ts-ignore\n            const loggedInUser = req.user as LoggedInUser\n            let isSSO = false\n            let newTokenResponse: any = {}\n            if (loggedInUser && loggedInUser.ssoRefreshToken) {\n                try {\n                    newTokenResponse = await identityManager.getRefreshToken(loggedInUser.ssoProvider, loggedInUser.ssoRefreshToken)\n                    if (newTokenResponse.error) {\n                        return res.status(401).json({ message: ErrorMessage.REFRESH_TOKEN_EXPIRED })\n                    }\n                    isSSO = true\n                } catch (error) {\n                    return res.status(401).json({ message: ErrorMessage.REFRESH_TOKEN_EXPIRED })\n                }\n            }","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/server/src/enterprise/middleware/passport/index.ts#L219-L255","documentation":"Returned as HTTP 401 Unauthorized (via res.sendStatus(401)) by the POST /api/v1/auth/refreshToken handler when the refreshToken cookie is absent. This is the very first guard in the refresh flow — it fires before jwt.verify, so it tells you the client never sent a refresh token at all, not that the token was invalid/expired. Unlike the other errors, this one returns a bare 401 status with no JSON body.","triggerScenarios":"POST /api/v1/auth/refreshToken called with no refreshToken cookie. Browser cleared cookies (logout, devtools clear, privacy mode). SameSite=lax cookie dropped because the request is cross-site. Cookie expired or never set because login didn't reach setTokenOrCookies. Client is a non-browser API client that never stored the refresh-token cookie.","commonSituations":"User opened the app in a new incognito window. Third-party cookie blocking stripped the refresh cookie. APP_URL changed so the cookie domain/path no longer matches. SECURE_COOKIES=true in dev over HTTP, so the browser refused to set the cookie. SPA on a different origin than the API. Token expiry handling in the client called refresh before login completed.","solutions":["Send the user back through /api/v1/auth/login to obtain a fresh pair of token + refreshToken cookies.","If you operate a non-browser client, capture Set-Cookie from the login response and replay the refreshToken cookie on refresh requests (use a cookie jar).","Verify SECURE_COOKIES / NODE_ENV / APP_URL so the cookie is actually being set in your environment — over HTTP in dev, set SECURE_COOKIES=false.","Confirm APP_URL origin matches the API origin, or adjust cookie sameSite/domain to fit your deployment.","In tests, attach Cookie: refreshToken=<jwt> to the refresh request.","On the client, only call /refreshToken after a prior successful login that returned Set-Cookie."],"exampleFix":"// before — non-browser client with no cookie jar\nawait axios.post('/api/v1/auth/refreshToken') // 401: no cookie sent\n\n// after — persist and replay the cookie\nconst jar = new CookieJar()\nconst client = axios.create({ jar, withCredentials: true })\nawait client.post('/api/v1/auth/login', { email, password }) // stores refreshToken\nawait client.post('/api/v1/auth/refreshToken')                // replays it","handlingStrategy":"validation","validationCode":"// before calling /refreshToken, confirm the cookie exists (browser) or the jar has it (node)\nasync function refreshIfPossible(): Promise<void> {\n  // browser\n  if (typeof document !== 'undefined') {\n    const hasRefresh = document.cookie.split('; ').some(c => c.startsWith('refreshToken='))\n    if (!hasRefresh) {\n      await auth.login(credentials) // no point refreshing without a cookie\n      return\n    }\n  }\n  await fetch('/api/v1/auth/refreshToken', { method: 'POST', credentials: 'include' })\n}","typeGuard":"// For a node client with a cookie jar — narrow to a cookie that has the refresh token\nfunction cookieJarHasRefresh(jar: { getCookiesSync: (url: string) => Array<{ key: string }> }, url: string): boolean {\n  return jar.getCookiesSync(url).some(c => c.key === 'refreshToken')\n}","tryCatchPattern":"// On 401 from a resource request, try refresh exactly once; if refresh itself 401s, send to login.\ntry {\n  return await api.callProtected()\n} catch (e) {\n  if (e.response?.status !== 401) throw e\n  try {\n    await api.refreshToken() // may throw 401 with no body — that's this error\n    return await api.callProtected()\n  } catch (refreshErr) {\n    if (refreshErr.response?.status === 401) {\n      await auth.redirectToLogin() // refresh cookie was missing — refresh cannot succeed\n      return\n    }\n    throw refreshErr\n  }\n}","preventionTips":["Always send credentials: 'include' (browser) or use a cookie jar (node) on every request so the refreshToken cookie round-trips.","Verify SECURE_COOKIES / NODE_ENV / APP_URL so the refresh cookie is actually being set in your environment (use SECURE_COOKIES=false over plain HTTP in dev).","Don't call /refreshToken before a successful login has stored the cookie.","Distinguish this 401 (no body, missing cookie) from the JWT-expired 401 (JSON body with REFRESH_TOKEN_EXPIRED) — only the latter is worth retrying.","In tests, attach Cookie: refreshToken=<jwt> from the login response's Set-Cookie."],"tags":["auth","cookies","jwt","refresh-token","session","flowise"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}