payloadcms/payload · error · UnauthorizedError
Unauthorized, you must be logged in to make this request.
Error message
Unauthorized, you must be logged in to make this request.
What it means
Thrown as UnauthorizedError (HTTP 401) by the experimental _internal_renderField server function when req.user is falsy. This server function renders a single field's custom components on the server and requires an authenticated admin session.
Source
Thrown at packages/ui/src/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.ts:53
*
* Examples:
* "collection.posts.richText"
* "global.siteSettings.content"
*/
schemaPath: string
}
export type RenderFieldServerFnReturnType = {} & FieldState['customComponents']
/**
* @experimental - may break in minor releases
*/
export const _internal_renderFieldHandler: ServerFunction<
RenderFieldServerFnArgs,
Promise<RenderFieldServerFnReturnType>
// eslint-disable-next-line @typescript-eslint/require-await
> = async ({ field: fieldArg, initialValue, path, req, schemaPath }) => {
if (!req.user) {
throw new UnauthorizedError()
}
const [entityType, entitySlug, ...fieldPath] = schemaPath.split('.')
const schemaMap = getSchemaMap({
collectionSlug: entityType === 'collection' ? entitySlug : undefined,
config: req.payload.config,
globalSlug: entityType === 'global' ? entitySlug : undefined,
i18n: req.i18n,
})
// Provide client schema map as it would have been provided if the target editor field would have been rendered.
// For lexical, only then will it contain all the lexical-internal entries
const clientSchemaMap = getClientSchemaMap({
collectionSlug: entityType === 'collection' ? entitySlug : undefined,
config: getClientConfig({
config: req.payload.config,
i18n: req.i18n,View on GitHub (pinned to 00c58b35c0)
Solutions
- Ensure the admin session is active and the cookie reaches the renderField server function.
- Gate client-side calls to renderField behind a user check so they aren't issued anonymously.
- Wire auth middleware to populate req.user before the server function executes.
Example fix
// before — calling renderField without ensuring auth
const result = await fetchServerFunction('renderField', { schemaPath, path })
// after — verify auth before calling
if (!user) redirect('/login')
const result = await fetchServerFunction('renderField', { schemaPath, path }) Defensive patterns
Strategy: validation
Validate before calling
function isLoggedIn(user: unknown): user is { id: string } {
return Boolean(user)
}
if (!isLoggedIn(req.user)) {
throw new Error('Login required to render this field.')
} Type guard
import { UnauthorizedError } from 'payload'
function isUnauthorized(err: unknown): err is UnauthorizedError {
return err instanceof UnauthorizedError
} Try / catch
try {
await fetchServerFunction('renderField', { field, schemaPath, path })
} catch (err) {
if (isUnauthorized(err)) {
redirectToLogin()
return
}
throw err
} Prevention
- Ensure the admin session is active before issuing renderField calls.
- Forward credentials with the RPC so req.user is populated.
- Gate client calls behind a user check to avoid anonymous RPCs.
When it happens
Trigger: The renderField server function is invoked (e.g. to server-render a field's custom component) while req.user is null — no session, expired session, or the call did not propagate auth.
Common situations: Field renders triggered after session expiry; a custom editor invoking the renderField RPC without forwarding credentials; SSR of a field before auth middleware populates req.user.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Could not find target field at schemaPath: ${schemaPath}
- Unauthorized
- Field config not found for ${schemaPath}
- No auth config found for collection: ${collection}
- Email or username is required.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/f2dbdc77d4e5530f.
Report an issue: GitHub.