{"record":{"id":"46604e8c3d41a48a","repo":"payloadcms/payload","slug":"unauthorized-46604e","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ui/src/elements/Nav/SidebarTabs/renderTabServerFn.ts","lineNumber":20,"sourceCode":"import type React from 'react'\n\nimport { RenderServerComponent } from '../../RenderServerComponent/index.js'\n\nexport type RenderTabServerFnArgs = {\n  searchParams?: Record<string, unknown>\n  tabSlug: string\n}\n\nexport type RenderTabServerFnReturnType = {\n  component: React.ReactNode\n}\n\nexport const renderTabHandler: ServerFunction<\n  RenderTabServerFnArgs,\n  RenderTabServerFnReturnType\n> = ({ req, searchParams, tabSlug }) => {\n  if (!req.user) {\n    throw new Error('Unauthorized')\n  }\n\n  const { importMap } = req.payload\n  const { tabs } = req.payload.config.admin.components?.sidebar || {}\n\n  if (!tabs) {\n    return { component: null }\n  }\n\n  const tabConfig = tabs.find((tab) => tab.slug === tabSlug)\n\n  if (!tabConfig) {\n    return { component: null }\n  }\n\n  try {\n    const component = RenderServerComponent({\n      Component: tabConfig.components.Content,","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/ui/src/elements/Nav/SidebarTabs/renderTabServerFn.ts#L2-L38","documentation":"A plain Error('Unauthorized') thrown by the renderTab server function when req.user is falsy. This server function renders a custom sidebar tab's React component; it requires an authenticated admin session. Because it throws a bare Error (not UnauthorizedError), it surfaces without an explicit HTTP status.","triggerScenarios":"The renderTab server function is invoked (sidebar tab render) while req.user is null — no session cookie, expired session, or the request reached the server function without auth context.","commonSituations":"Sidebar tab attempts to render on a page load after session expiry; the server function is called from a context that does not propagate the auth cookie; custom sidebar tab registered without considering anonymous access.","solutions":["Ensure the admin session cookie is present and not expired when the sidebar tab renders.","If the tab should be visible anonymously, gate the renderTab call on the client with a user check first.","Register auth middleware so req.user is populated before the server function runs."],"exampleFix":"// before\nexport const renderTabHandler = ({ req, searchParams, tabSlug }) => {\n  if (!req.user) throw new Error('Unauthorized')\n  ...\n}\n\n// after — throw the proper UnauthorizedError so the boundary maps it to 401\nimport { UnauthorizedError } from 'payload'\nexport const renderTabHandler = ({ req, searchParams, tabSlug }) => {\n  if (!req.user) throw new UnauthorizedError()\n  ...\n}","handlingStrategy":"validation","validationCode":"function canRenderTab(user: unknown): user is { id: string } {\n  return Boolean(user)\n}\n\nif (!canRenderTab(req.user)) {\n  // skip the renderTab call; the tab requires auth\n  return { component: null }\n}","typeGuard":"function isUnauthorized(err: unknown): err is Error {\n  return err instanceof Error && err.message === 'Unauthorized'\n}","tryCatchPattern":"try {\n  const { component } = await fetchServerFunction('renderTab', { tabSlug })\n} catch (err) {\n  if (isUnauthorized(err)) {\n    redirectToLogin()\n    return\n  }\n  throw err\n}","preventionTips":["Gate client-side renderTab calls behind a logged-in check.","Use UnauthorizedError instead of a bare 'Unauthorized' string so callers can type-narrow.","Ensure auth middleware populates req.user before the server function runs."],"tags":["ui","server-function","auth","sidebar","unauthorized"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}