payloadcms/payload · error · APIError

Invalid ID value in ${JSON.stringify(queryValue)}

Error message

Invalid ID value in ${JSON.stringify(queryValue)}

What it means

`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.

Source

Thrown at packages/drizzle/src/queries/parseParams.ts:491

                  let isInvalid = false
                  for (const val of queryValue) {
                    if (typeof val === 'number' || val === null) {
                      continue
                    }
                    if (typeof val === 'string') {
                      if (!isValidStringID(val)) {
                        isInvalid = true
                        break
                      } else {
                        continue
                      }
                    }
                    isInvalid = true
                    break
                  }

                  if (isInvalid) {
                    throw new APIError(`Invalid ID value in ${JSON.stringify(queryValue)}`)
                  }

                  constraints.push(
                    sql.raw(
                      `"${getTableName(resolvedColumn.table)}"."${resolvedColumn.name}" ${operator === 'in' ? 'IN' : 'NOT IN'} (${queryValue
                        .map((e) => {
                          if (e === null) {
                            return `NULL`
                          }

                          if (typeof e === 'number') {
                            return e
                          }

                          return `'${e}'`
                        })
                        .join(',')})`,
                    ),

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Map the array to primitive IDs before querying: `ids.map(x => typeof x === 'object' ? x.id : x)`.
  2. Validate each string ID with `/^[\w-]+$/` (or `isValidStringID`) and strip/reject invalid entries.
  3. Drop non-numeric, non-null, non-string values from the array before sending the query.
  4. If IDs legitimately contain other characters, use a non-id field or disable the limited-bound-parameters path per the adapter docs.

Example fix

// before
await payload.find({ collection: 'posts', where: { id: { in: [1, '2', { id: 3 }, 'a b'] } } })
// after
const raw = [1, '2', someObj.id, 'a-b'] // extract ids, sanitize strings
const ids = raw.filter(v => typeof v === 'number' || v === null || (typeof v === 'string' && /^\w-$/.test(v)))
await payload.find({ collection: 'posts', where: { id: { in: ids } } })
Defensive patterns

Strategy: validation

Validate before calling

function isValidStringID(value) { return /^[\w-]+$/.test(value) }
function sanitizeIdArray(arr) {
  return arr.filter(v =>
    v === null ||
    typeof v === 'number' ||
    (typeof v === 'string' && isValidStringID(v))
  )
}
const ids = sanitizeIdArray(rawIds)
await payload.find({ collection, where: { id: { in: ids } } })

Type guard

const isValidIdValue = (v): boolean =>
  v === null || typeof v === 'number' || (typeof v === 'string' && /^\w-$/.test(v))

Try / catch

try {
  await payload.find({ collection, where: { id: { in: ids } } })
} catch (err) {
  if (err?.statusCode === 400 && /Invalid ID value in/.test(err?.message)) {
    return res.status(400).json({ error: 'One or more IDs are malformed.' })
  }
  throw err
}

Prevention

When it happens

Trigger: 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.).

Common situations: 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.

Related errors


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