payloadcms/payload · error · APIError

Only 'equals' operator is supported for polymorphic relation

Error message

Only 'equals' operator is supported for polymorphic relationship object notation. Given - ${operator}

What it means

Thrown when querying a polymorphic relationship or upload field using the object notation (e.g. { relationTo: 'posts', value: '...' }) with any operator other than 'equals'. Polymorphic object notation resolves to a single (relationTo, value) pair, so only exact equality is meaningful; other operators (in, not_in, like, etc.) are rejected up front in sanitizeQueryValue before the SQL is built.

Source

Thrown at packages/drizzle/src/queries/sanitizeQueryValue.ts:157

      formattedValue = converted
    }
  }

  if (field.type === 'relationship' || field.type === 'upload') {
    if (val === 'null') {
      formattedValue = null
    } else if (!(formattedValue === null || typeof formattedValue === 'boolean')) {
      // convert the value to the idType of the relationship
      let idType: 'number' | 'text'
      if (typeof field.relationTo === 'string') {
        idType = getCollectionIdType({
          adapter,
          collection: adapter.payload.collections[field.relationTo],
        })
      } else {
        if (isPolymorphicRelationship(val)) {
          if (operator !== 'equals') {
            throw new APIError(
              `Only 'equals' operator is supported for polymorphic relationship object notation. Given - ${operator}`,
            )
          }
          idType = getCollectionIdType({
            adapter,
            collection: adapter.payload.collections[val.relationTo],
          })

          if (isRawConstraint(val.value)) {
            return {
              operator,
              value: val.value.value,
            }
          }
          return {
            operator,
            value: idType === 'number' ? Number(val.value) : String(val.value),
          }

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Switch the operator for that polymorphic condition to 'equals' and pass a single { relationTo, value } object.
  2. If you need to match multiple IDs, query each relationTo separately or use an $or of multiple 'equals' conditions.
  3. If you must use 'in', pass a flat array of IDs and ensure the field is not polymorphic, or restructure the schema so the relation targets a single collection.

Example fix

// before
where: {
  relatedDocs: { in: [{ relationTo: 'posts', value: 'abc' }] }
}
// after
where: {
  relatedDocs: { equals: { relationTo: 'posts', value: 'abc' } }
}
Defensive patterns

Strategy: validation

Validate before calling

function buildPolymorphicWhere(field, operator, value) {
  if (value && typeof value === 'object' && 'relationTo' in value && operator !== 'equals') {
    throw new Error(`Polymorphic object notation requires operator 'equals', got '${operator}'`)
  }
  return { [field]: { [operator]: value } }
}

Type guard

const isPolymorphicObjectValue = (v) => v !== null && typeof v === 'object' && 'relationTo' in v && 'value' in v

Try / catch

try {
  await payload.find({ collection: 'docs', where })
} catch (err) {
  if (/Only 'equals' operator is supported for polymorphic/.test(err.message)) {
    // rewrite the offending condition to use 'equals'
  } else throw err
}

Prevention

When it happens

Trigger: A REST/Local/GQL API query against a polymorphic relationship field whose 'relationTo' is an array, passing an object value like { relationTo, value } together with an operator such as 'in', 'not_in', 'like', or 'exists' in the where clause.

Common situations: Trying to reuse a query shape that worked on a mono-collection relationship field against a polymorphic field; migrating a query from Mongo to the Drizzle adapter and keeping a multi-value operator; building a where clause dynamically and defaulting to 'in' for arrays of IDs.

Related errors


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