payloadcms/payload · error · PayloadSDKError
${message}
Error message
${message} What it means
Thrown by the Payload SDK's request helper whenever the underlying `fetch` returns a non-OK status. It parses the response body for `errors`/`message` (falling back to `response.statusText`) and wraps them in a `PayloadSDKError` carrying `status`, `response`, and the structured `errors` array. This is the SDK's universal catch-all — the real cause is whatever the server returned (validation, auth, not-found, server error).
Source
Thrown at packages/sdk/src/index.ts:340
if (!response.ok) {
let errorData: {
message?: string
} & Partial<ErrorResult> = {}
try {
errorData = await response.json()
} catch {
// Response body may not be JSON
}
const errors: ErrorResult['errors'] = errorData.errors ?? [
{ message: errorData.message ?? response.statusText },
]
const message = errors[0]?.message ?? response.statusText
throw new PayloadSDKError({
errors,
message,
response,
status: response.status,
})
}
return response
}
resetPassword<TSlug extends AuthCollectionSlug<T>>(
options: ResetPasswordOptions<T, TSlug>,
init?: RequestInit,
): Promise<ResetPasswordResult<T, TSlug>> {
return resetPassword(this, options, init)
}
restoreGlobalVersion<TSlug extends GlobalSlug<T>>(View on GitHub (pinned to 00c58b35c0)
Solutions
- Inspect `error.status` to route handling (401 → re-auth, 404 → not-found UX, 400 → show `error.errors`)
- Read `error.errors` (the structured array) for field-level validation messages
- If `error.message === response.statusText` and the body was non-JSON, a proxy/CDN likely intercepted — check the raw network response
- Reproduce the request with the same headers/cookie via curl to see the raw server response
Example fix
// before — unhandled rejection
await sdk.find({ collection: 'posts', where: { id: { equals: 'bad' } } })
// after — branch on status
try {
await sdk.find({ collection: 'posts', where: { id: { equals: id } } })
} catch (e) {
if (e instanceof PayloadSDKError) {
if (e.status === 401) await relogin()
else if (e.status === 400) showErrors(e.errors)
}
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the call shape against the collection schema where possible // (field types, required fields) to avoid the common 400 path before it hits the server
Type guard
import { PayloadSDKError } from '@payloadcms/sdk'
// or: function isPayloadSDKError(e: unknown): e is PayloadSDKError { return e instanceof PayloadSDKError }
function isPayloadSDKError(e: unknown): e is { status: number; errors: { message: string }[]; message: string } {
return !!e && typeof (e as any).status === 'number' && Array.isArray((e as any).errors)
} Try / catch
try {
await sdk.find({ collection: 'posts', where })
} catch (e) {
if (isPayloadSDKError(e)) {
if (e.status === 401) await relogin()
else if (e.status === 400) showFieldErrors(e.errors)
else if (e.status === 404) showNotFound()
}
throw e
} Prevention
- Always handle the SDK promise — an unhandled rejection loses the structured `errors` array
- Branch on `error.status` rather than parsing `error.message`
- For non-JSON bodies (proxy/CDN errors), fall back to `response.statusText` diagnostics
- Log `error.errors` verbatim so field-level causes are visible in monitoring
When it happens
Trigger: Any SDK call (find, create, update, delete, auth) where the server responds with a non-2xx status — validation error (400), unauthorized (401), forbidden (403), not found (404), or server error (500). The body is JSON with `errors` or `message`, or non-JSON (then `statusText` is used).
Common situations: Sending invalid field values that fail server-side validation; expired/missing auth token; querying a non-existent collection or document ID; server threw during a hook; network proxy returning an HTML error page (non-JSON body).
Related errors
- Content-Type expected to be application/json
- Invalid template given
- Invalid database type given. Valid types are: ${Object.value
- No version or tag "${version}" found for package: ${packageN
- Either collection or globalSlug must be passed.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/576a1f671649e3fc.
Report an issue: GitHub.