payloadcms/payload · error · InvalidConfiguration

Unique is not supported in Postgres for hasMany number field

Error message

Unique is not supported in Postgres for hasMany number fields.

What it means

Thrown during schema traversal (traverseFields.ts) when a number field that is hasMany (array of numbers) is declared with `unique: true`. A hasMany number field is stored in a separate rows table (one row per array element), and a SQL UNIQUE constraint across an array is not meaningful, so the Postgres adapter rejects it. The same field may use `index: true` instead.

Source

Thrown at packages/drizzle/src/schema/traverseFields.ts:743

      case 'number': {
        if (field.hasMany) {
          const isLocalized =
            Boolean(isFieldLocalized && adapter.payload.config.localization) ||
            withinLocalizedArrayOrBlock ||
            forceLocalized

          if (isLocalized) {
            hasLocalizedManyNumberField = true
          }

          if (field.index) {
            hasManyNumberField = 'index'
          } else if (!hasManyNumberField) {
            hasManyNumberField = true
          }

          if (field.unique) {
            throw new InvalidConfiguration(
              'Unique is not supported in Postgres for hasMany number fields.',
            )
          }
        } else {
          targetTable[fieldName] = withDefault(
            {
              name: columnName,
              type: 'numeric',
            },
            field,
          )
        }

        break
      }

      case 'point': {
        targetTable[fieldName] = withDefault(

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Remove `unique: true` from the hasMany number field.
  2. If you need per-element uniqueness, enforce it at the application layer or via a custom validation hook.
  3. If only a single number must be unique, split into a separate non-hasMany number field with unique: true.

Example fix

// before
{ name: 'codes', type: 'number', hasMany: true, unique: true }
// after
{ name: 'codes', type: 'number', hasMany: true, index: true }
Defensive patterns

Strategy: validation

Validate before calling

function assertNoUniqueOnHasManyNumber(fields) {
  for (const f of fields) {
    if (f.type === 'number' && f.hasMany && f.unique) {
      throw new Error(`Field ${f.name}: unique is not allowed on hasMany number fields`)
    }
  }
}

Type guard

const isHasManyNumber = (f) => f.type === 'number' && !!f.hasMany

Prevention

When it happens

Trigger: Defining a field `{ name: 'tags', type: 'number', hasMany: true, unique: true }` in a collection or global field config.

Common situations: Copy-pasting a single-value number field config and adding hasMany without removing unique; assuming 'unique array' is supported like in Mongo.

Related errors


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