{"record":{"id":"98242106048c95e1","repo":"payloadcms/payload","slug":"unauthorized-982421","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.ts","lineNumber":28,"sourceCode":"\nimport { RenderServerComponent } from '../../../../../elements/RenderServerComponent/index.js'\n\nexport type GetDefaultLayoutServerFnArgs = Record<string, never>\n\nexport type GetDefaultLayoutServerFnReturnType = {\n  layout: WidgetInstanceClient[]\n}\n\n/**\n * Server function to get the default dashboard layout on-demand.\n * Used when resetting the dashboard to its default configuration.\n */\nexport const getDefaultLayoutHandler: ServerFunction<\n  GetDefaultLayoutServerFnArgs,\n  Promise<GetDefaultLayoutServerFnReturnType>\n> = async ({ cookies, locale, permissions, req }) => {\n  if (!req.user) {\n    throw new Error('Unauthorized')\n  }\n\n  const { defaultLayout = [], widgets = [] } = req.payload.config.admin.dashboard || {}\n  const { importMap } = req.payload\n\n  const layoutItems = await getItemsFromConfig(defaultLayout, req, widgets)\n\n  const layout: WidgetInstanceClient[] = layoutItems.map((layoutItem) => {\n    const widgetSlug = layoutItem.id.slice(0, layoutItem.id.lastIndexOf('-'))\n    return {\n      component: RenderServerComponent({\n        Component: widgets.find((widget) => widget.slug === widgetSlug)?.Component,\n        importMap,\n        serverProps: {\n          cookies,\n          locale,\n          permissions,\n          req,","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/ui/src/views/Dashboard/Default/ModularDashboard/renderWidget/getDefaultLayoutServerFn.ts#L10-L46","documentation":"The dashboard's get-default-layout server function throws a plain `Error('Unauthorized')` when `req.user` is missing. Resetting the dashboard to its default layout reads from `config.admin.dashboard` and renders widgets server-side, which is an authenticated admin action, so anonymous requests are rejected up front.","triggerScenarios":"Clicking 'reset to default layout' after the session expired, loading the dashboard while logged out, the auth cookie not forwarded to the server function, an auth strategy that leaves `req.user` unset.","commonSituations":"Idle admin sessions that lapse, cross-origin dashboard requests without credentials, auth plugin misconfiguration, proxy stripping session cookies.","solutions":["Ensure the user is logged in before the reset action is available.","Confirm the auth cookie is sent with the dashboard server-function requests.","Verify the auth strategy populates `req.user` for admin routes.","Re-authenticate and retry the reset."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!req.user) {\n  // gate the 'reset to default layout' action behind a live session check\n}","typeGuard":"function isAuthenticated<\n  R extends { user?: unknown },\n>(req: R): req is R & { user: NonNullable<R['user']> } {\n  return !!req.user\n}","tryCatchPattern":"try {\n  await getDefaultLayout(args)\n} catch (err) {\n  if (err instanceof Error && err.message === 'Unauthorized') {\n    // prompt re-login, then retry the reset\n  } else {\n    throw err\n  }\n}","preventionTips":["Disable the reset-to-default action when the session is stale.","Forward the auth cookie with dashboard server-function requests.","Confirm the auth strategy populates `req.user` for admin routes.","Re-authenticate and retry on session expiry."],"tags":["auth","dashboard","server-functions","unauthorized"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}