{"record":{"id":"5f7eb067a5e9a771","repo":"payloadcms/payload","slug":"invalid-id-value-in-json-stringify-queryvalue","errorCode":null,"errorMessage":"Invalid ID value in ${JSON.stringify(queryValue)}","messagePattern":"Invalid ID value in (.+?)","errorType":"http","errorClass":"APIError","httpStatus":500,"severity":"error","filePath":"packages/drizzle/src/queries/parseParams.ts","lineNumber":491,"sourceCode":"                  let isInvalid = false\n                  for (const val of queryValue) {\n                    if (typeof val === 'number' || val === null) {\n                      continue\n                    }\n                    if (typeof val === 'string') {\n                      if (!isValidStringID(val)) {\n                        isInvalid = true\n                        break\n                      } else {\n                        continue\n                      }\n                    }\n                    isInvalid = true\n                    break\n                  }\n\n                  if (isInvalid) {\n                    throw new APIError(`Invalid ID value in ${JSON.stringify(queryValue)}`)\n                  }\n\n                  constraints.push(\n                    sql.raw(\n                      `\"${getTableName(resolvedColumn.table)}\".\"${resolvedColumn.name}\" ${operator === 'in' ? 'IN' : 'NOT IN'} (${queryValue\n                        .map((e) => {\n                          if (e === null) {\n                            return `NULL`\n                          }\n\n                          if (typeof e === 'number') {\n                            return e\n                          }\n\n                          return `'${e}'`\n                        })\n                        .join(',')})`,\n                    ),","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/queries/parseParams.ts#L473-L509","documentation":"`APIError` from `parseParams` in the optimized `in`/`not_in` path on the `id` field when `adapter.limitedBoundParameters` is set: every element of the array value must be a number, `null`, or a valid string ID (matching `/^[\\w-]+$/`). If any element is another type or a string with invalid characters, the raw-SQL interpolation path is unsafe and the query is rejected with a 400.","triggerScenarios":"Calling `payload.find({ collection, where: { id: { in: [...] } } })` (or `not_in`) on an adapter with `limitedBoundParameters`, where the array contains an object, boolean, symbol, or a string that fails `isValidStringID` (spaces, punctuation, etc.).","commonSituations":"Passing objects (`{ id: 1 }`) instead of raw IDs into an `in` list; IDs containing characters outside `[A-Za-z0-9_-]`; mixing types in an `in` array; client form data feeding unparsed values into an id query.","solutions":["Map the array to primitive IDs before querying: `ids.map(x => typeof x === 'object' ? x.id : x)`.","Validate each string ID with `/^[\\w-]+$/` (or `isValidStringID`) and strip/reject invalid entries.","Drop non-numeric, non-null, non-string values from the array before sending the query.","If IDs legitimately contain other characters, use a non-id field or disable the limited-bound-parameters path per the adapter docs."],"exampleFix":"// before\nawait payload.find({ collection: 'posts', where: { id: { in: [1, '2', { id: 3 }, 'a b'] } } })\n// after\nconst raw = [1, '2', someObj.id, 'a-b'] // extract ids, sanitize strings\nconst ids = raw.filter(v => typeof v === 'number' || v === null || (typeof v === 'string' && /^\\w-$/.test(v)))\nawait payload.find({ collection: 'posts', where: { id: { in: ids } } })","handlingStrategy":"validation","validationCode":"function isValidStringID(value) { return /^[\\w-]+$/.test(value) }\nfunction sanitizeIdArray(arr) {\n  return arr.filter(v =>\n    v === null ||\n    typeof v === 'number' ||\n    (typeof v === 'string' && isValidStringID(v))\n  )\n}\nconst ids = sanitizeIdArray(rawIds)\nawait payload.find({ collection, where: { id: { in: ids } } })","typeGuard":"const isValidIdValue = (v): boolean =>\n  v === null || typeof v === 'number' || (typeof v === 'string' && /^\\w-$/.test(v))","tryCatchPattern":"try {\n  await payload.find({ collection, where: { id: { in: ids } } })\n} catch (err) {\n  if (err?.statusCode === 400 && /Invalid ID value in/.test(err?.message)) {\n    return res.status(400).json({ error: 'One or more IDs are malformed.' })\n  }\n  throw err\n}","preventionTips":["Extract raw IDs from objects before building in/not_in arrays.","Validate string IDs against /^[\\w-]+$/ before sending queries.","Drop non-numeric, non-null, non-string entries from id arrays.","Sanitize client-supplied id lists at the API boundary."],"tags":["query","where","validation","in-operator","api-error"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}