payloadcms/payload · error · TypeError
JSONObject cannot represent non-object value: ${value}
Error message
JSONObject cannot represent non-object value: ${value} What it means
Thrown by the `ensureObject` helper used as `parseValue` and `serialize` for the `JSONObject` GraphQL scalar. It fires whenever the value is not a plain object — i.e. it is not `typeof 'object'`, or is `null`, or is an array. The scalar intentionally only accepts JSON objects (not arrays or primitives), unlike the more permissive `JSON` scalar. This protects the schema contract that a `JSONObject` field is always a `{ }` value.
Source
Thrown at packages/graphql/src/packages/graphql-type-json/index.ts:10
import { GraphQLScalarType } from 'graphql'
import { Kind, print } from 'graphql/language/index.js'
function identity(value) {
return value
}
function ensureObject(value) {
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
throw new TypeError(`JSONObject cannot represent non-object value: ${value}`)
}
return value
}
function parseObject(typeName, ast, variables) {
const value = Object.create(null)
ast.fields.forEach((field) => {
value[field.name.value] = parseLiteral(typeName, field.value, variables)
})
return value
}
function parseLiteral(typeName, ast, variables) {
switch (ast.kind) {
case Kind.BOOLEAN:
case Kind.STRING:View on GitHub (pinned to 00c58b35c0)
Solutions
- Send a plain object `{ }` instead of an array or primitive for the `JSONObject` argument.
- If arbitrary JSON (arrays/primitives) is legitimately needed, switch the schema field from `GraphQLJSONObject` to `GraphQLJSON`.
- Validate/coerce the value client-side: if `Array.isArray(v)` or `v === null` or `typeof v !== 'object'`, wrap or reject before sending.
Example fix
// before — mutation arg typed JSONObject, value is an array
variables: { filters: [{ field: 'x', op: 'eq' }] }
// after — wrap in an object
variables: { filters: { rules: [{ field: 'x', op: 'eq' }] } } Defensive patterns
Strategy: type-guard
Validate before calling
function ensurePlainObject(v) {
if (typeof v !== 'object' || v === null || Array.isArray(v)) {
throw new Error('JSONObject argument must be a plain object')
}
return v
} Type guard
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
} Try / catch
try {
await client.request(mutation, { input: ensurePlainObject(value) })
} catch (e) {
if (e instanceof TypeError && /JSONObject cannot represent non-object/.test(e.message)) {
// wrap arrays/primitives in an object or use the JSON scalar
}
throw e
} Prevention
- Prefer sending JSON scalars via `$variables` rather than inline literals.
- Validate with `isPlainObject` before the request.
- Choose `JSON` over `JSONObject` when arrays/primitives are valid values.
When it happens
Trigger: A GraphQL mutation/argument typed `JSONObject` receives a primitive (string/number/boolean), `null` (non-nullable), or an array in the variables. Also fires during serialization if a resolver returns an array or null for a `JSONObject` field.
Common situations: Confusing `JSON` (any JSON value) with `JSONObject` (object only); passing `[]` where a settings object is expected; a resolver returning `null` for a non-null JSONObject field; frontend sending `[1,2,3]` as JSON-stringified body for a field documented as an object.
Related errors
- JSONObject cannot represent non-object value: ${print(ast)}
- ${typeName} cannot represent value: ${print(ast)}
- ${value} is not allowed as a JSON query value
- ${value} is not allowed as a JSON query value
- Field ${field.label} has invalid relationship '${relationshi
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/05e66b17e298ed87.
Report an issue: GitHub.