payloadcms/payload · error · TypeError

JSONObject cannot represent non-object value: ${print(ast)}

Error message

JSONObject cannot represent non-object value: ${print(ast)}

What it means

Thrown by the `parseLiteral` of the `JSONObject` scalar when the AST node supplied inline is not an `OBJECT` kind. Because `JSONObject` only represents objects, an inline array, string, number, boolean, or null literal as a JSONObject argument is rejected with the printed AST. This is the literal-parsing counterpart of the `ensureObject` value check.

Source

Thrown at packages/graphql/src/packages/graphql-type-json/index.ts:64

// This named export is intended for users of CommonJS. Users of ES modules
//  should instead use the default export.
export const GraphQLJSON = new GraphQLScalarType({
  name: 'JSON',
  description:
    'The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).',
  parseLiteral: (ast, variables) => parseLiteral('JSON', ast, variables),
  parseValue: identity,
  serialize: identity,
  specifiedByURL: 'http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf',
})

export const GraphQLJSONObject = new GraphQLScalarType({
  name: 'JSONObject',
  description:
    'The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).',
  parseLiteral: (ast, variables) => {
    if (ast.kind !== Kind.OBJECT) {
      throw new TypeError(`JSONObject cannot represent non-object value: ${print(ast)}`)
    }

    return parseObject('JSONObject', ast, variables)
  },
  parseValue: ensureObject,
  serialize: ensureObject,
  specifiedByURL: 'http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf',
})

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Provide the value as a `$variable` of type `JSONObject` so it goes through `parseValue`/`ensureObject` with a real object.
  2. Make the inline literal an object: `{ }`.
  3. If a non-object JSON value is valid here, change the scalar to `JSON` instead of `JSONObject`.

Example fix

# before — inline array for a JSONObject argument
mutation { update(cfg: [1, 2, 3]) { id } }

# after — inline object, or use a variable
mutation Update($cfg: JSONObject) { update(cfg: $cfg) { id } }
Defensive patterns

Strategy: validation

Validate before calling

function ensureObjectForGraphQL(v) {
  if (typeof v !== 'object' || v === null || Array.isArray(v)) {
    throw new Error('Provide an object literal or a $variable for JSONObject')
  }
  return v
}

Type guard

function isJSONObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v)
}

Try / catch

try {
  await client.request(mutation, { cfg: ensureObjectForGraphQL(cfg) })
} catch (e) {
  if (e instanceof TypeError && /JSONObject cannot represent non-object value/.test(e.message)) {
    // pass an object literal or a $variable of type JSONObject
  }
  throw e
}

Prevention

When it happens

Trigger: Writing an inline literal that is not an object for a `JSONObject` argument: e.g. `mutation($` with `filters: [1,2]` inline, or `settings: "default"`. Using a variable avoids this path entirely.

Common situations: Inline query literals for a JSONObject field; auto-generated queries that stringify arrays; developer copying a `JSON`-style example into a `JSONObject` field.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/c679ea8bdf0dd19d. Report an issue: GitHub.