payloadcms/payload · error · APIError

${value} is not allowed as a JSON query value

Error message

${value} is not allowed as a JSON query value

What it means

Thrown by escapeSQLValue when a JSON query value is a string containing characters outside the safe allowlist regex /^\w @.\-+:*$/. The function is used for inline JSON-path query values where parameterization is not possible, so only a strict character set is permitted to prevent injection. Numbers and booleans pass through; null passes through; other types throw a separate 'Invalid value type' error.

Source

Thrown at packages/drizzle/src/utilities/escapeSQLValue.ts:19

import { APIError } from 'payload'

export const SAFE_STRING_REGEX = /^[\w @.\-+:]*$/

export const escapeSQLValue = (value: unknown): boolean | null | number | string => {
  if (value === null) {
    return null
  }

  if (typeof value === 'number' || typeof value === 'boolean') {
    return value
  }

  if (typeof value !== 'string') {
    throw new Error('Invalid value type')
  }

  if (!SAFE_STRING_REGEX.test(value)) {
    throw new APIError(`${value} is not allowed as a JSON query value`, 400)
  }

  const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')

  return escaped
}

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Sanitize/encode the input so it contains only word chars, spaces, and the allowed punctuation before passing it as a JSON query value.
  2. Prefer a parameterized query path (non-JSON column comparison) instead of JSON-path matching for arbitrary user input.
  3. If the value legitimately needs richer characters, redesign the query to use a parameterized LIKE/equals on a normal column.

Example fix

// before
where: { 'jsonField.path': { equals: userInput } } // userInput has quotes/semicolons
// after
if (!/^[\w @.\-+:]*$/.test(userInput)) throw new APIError('bad input', 400)
where: { 'jsonField.path': { equals: userInput } }
Defensive patterns

Strategy: validation

Validate before calling

const SAFE = /^[\w @.\-+:]*$/
function assertSafeJsonValue(v) {
  if (typeof v === 'string' && !SAFE.test(v)) {
    throw new Error('Value contains disallowed characters for JSON query')
  }
}

Type guard

const isSafeStringValue = (v) => typeof v !== 'string' || /^[\w @.\-+:]*$/.test(v)

Prevention

When it happens

Trigger: Constructing a JSON query (e.g. against a JSON/JSONB column or a rich text field) with a value containing quotes, semicolons, angle brackets, or any char outside the allowlist.

Common situations: Passing user-supplied free-text into a JSON query value; building a query with a URL, querystring, or HTML payload as the comparison value.

Related errors


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