{"record":{"id":"3527b3ac29c162d3","repo":"payloadcms/payload","slug":"value-is-not-allowed-as-a-json-query-value-3527b3","errorCode":null,"errorMessage":"${value} is not allowed as a JSON query value","messagePattern":"(.+?) is not allowed as a JSON query value","errorType":"http","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/drizzle/src/utilities/escapeSQLValue.ts","lineNumber":19,"sourceCode":"import { APIError } from 'payload'\n\nexport const SAFE_STRING_REGEX = /^[\\w @.\\-+:]*$/\n\nexport const escapeSQLValue = (value: unknown): boolean | null | number | string => {\n  if (value === null) {\n    return null\n  }\n\n  if (typeof value === 'number' || typeof value === 'boolean') {\n    return value\n  }\n\n  if (typeof value !== 'string') {\n    throw new Error('Invalid value type')\n  }\n\n  if (!SAFE_STRING_REGEX.test(value)) {\n    throw new APIError(`${value} is not allowed as a JSON query value`, 400)\n  }\n\n  const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n\n  return escaped\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/utilities/escapeSQLValue.ts#L1-L26","documentation":"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.","triggerScenarios":"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.","commonSituations":"Passing user-supplied free-text into a JSON query value; building a query with a URL, querystring, or HTML payload as the comparison value.","solutions":["Sanitize/encode the input so it contains only word chars, spaces, and the allowed punctuation before passing it as a JSON query value.","Prefer a parameterized query path (non-JSON column comparison) instead of JSON-path matching for arbitrary user input.","If the value legitimately needs richer characters, redesign the query to use a parameterized LIKE/equals on a normal column."],"exampleFix":"// before\nwhere: { 'jsonField.path': { equals: userInput } } // userInput has quotes/semicolons\n// after\nif (!/^[\\w @.\\-+:]*$/.test(userInput)) throw new APIError('bad input', 400)\nwhere: { 'jsonField.path': { equals: userInput } }","handlingStrategy":"validation","validationCode":"const SAFE = /^[\\w @.\\-+:]*$/\nfunction assertSafeJsonValue(v) {\n  if (typeof v === 'string' && !SAFE.test(v)) {\n    throw new Error('Value contains disallowed characters for JSON query')\n  }\n}","typeGuard":"const isSafeStringValue = (v) => typeof v !== 'string' || /^[\\w @.\\-+:]*$/.test(v)","tryCatchPattern":null,"preventionTips":["Never feed raw user free-text into JSON query values.","Prefer parameterized comparisons on normal columns for arbitrary input."],"tags":["query","security","injection","json","validation"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}