{"record":{"id":"2cb7f3f09b385b53","repo":"makeplane/plane","slug":"auth-missing-credentials","errorCode":"AUTH_MISSING_CREDENTIALS","errorMessage":"Credentials not provided","messagePattern":"Credentials not provided","errorType":"error_code","errorClass":"AppError","httpStatus":null,"severity":"critical","filePath":"apps/live/src/lib/auth.ts","lineNumber":57,"sourceCode":"  // the cookies are not passed in the request headers)\n  try {\n    const parsedToken = JSON.parse(token) as TUserDetails;\n    userId = parsedToken.id;\n    cookie = parsedToken.cookie;\n  } catch (error) {\n    const appError = new AppError(error, {\n      context: { operation: \"onAuthenticate\" },\n    });\n    logger.error(\"Token parsing failed, using request headers\", appError);\n  } finally {\n    // If cookie is still not found, fallback to request headers\n    if (!cookie) {\n      cookie = requestHeaders.cookie?.toString();\n    }\n  }\n\n  if (!cookie || !userId) {\n    const appError = new AppError(\"Credentials not provided\", { code: \"AUTH_MISSING_CREDENTIALS\" });\n    logger.error(\"Credentials not provided\", appError);\n    throw appError;\n  }\n\n  // set cookie in context, so it can be used throughout the ws connection\n  context.cookie = cookie ?? requestParameters.get(\"cookie\") ?? \"\";\n  context.documentType = requestParameters.get(\"documentType\")?.toString() as TDocumentTypes;\n  context.projectId = requestParameters.get(\"projectId\");\n  context.userId = userId;\n  context.workspaceSlug = requestParameters.get(\"workspaceSlug\");\n\n  return await handleAuthentication({\n    cookie: context.cookie,\n    userId: context.userId,\n  });\n};\n\nexport const handleAuthentication = async ({ cookie, userId }: { cookie: string; userId: string }) => {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/live/src/lib/auth.ts#L39-L75","documentation":"In the Live (Hocuspocus) WebSocket authentication hook, after attempting to read a cookie from request parameters and falling back to request headers, the code requires both a cookie and a userId. If neither resolves, it raises an AppError with code AUTH_MISSING_CREDENTIALS and aborts the connection. This is the gatekeeper for the collaborative editing socket.","triggerScenarios":"Connecting to the Live WS endpoint without a session cookie (anonymous), with an expired/invalid session that yields no userId, or from a client that sends neither cookie param nor Cookie header.","commonSituations":"Cookie blocked by SameSite/Secure cross-origin; dev environment without a logged-in session; proxy stripping the Cookie header; token parsing silently failed so userId is empty even though a cookie was present.","solutions":["Ensure the browser has an authenticated session cookie before opening the Live socket (log in first).","If behind a proxy, verify the Cookie header is forwarded to the WS handshake.","Check logs for the preceding 'Token parsing failed' warning — a present cookie with empty userId usually means token decode failed.","Confirm SameSite/Secure cookie attributes allow the WS origin."],"exampleFix":"// before\nnew HocuspocusProvider({ url, name: docName });\n\n// after\nif (!document.cookie.includes('session')) {\n  await redirectToLogin();\n}\nnew HocuspocusProvider({ url, name: docName });","handlingStrategy":"validation","validationCode":"function hasSessionCookie(): boolean { return /session/i.test(document.cookie); }\nif (!hasSessionCookie()) { await redirectToLogin(); }","typeGuard":null,"tryCatchPattern":"// at the WS provider onError/onAuthenticationFailed\nprovider.on('authenticationFailed', () => { redirectToLogin(); });","preventionTips":["Log in before opening the Live socket","Forward Cookie header through proxies","Watch for the 'Token parsing failed' log preceding this","Verify SameSite/Secure allow the WS origin"],"tags":["auth","websocket","live","session","credentials"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}