payloadcms/payload · error · InvalidConfiguration

Unique is not supported in Postgres for hasMany text fields.

Error message

Unique is not supported in Postgres for hasMany text fields.

What it means

Thrown during schema traversal when a text field that is hasMany is declared with `unique: true`. Like the number case, a hasMany text field is materialized as multiple rows in a separate table, so a UNIQUE constraint is not applicable; the adapter rejects the config at build time. `index: true` is allowed.

Source

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

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

          if (isLocalized) {
            hasLocalizedManyTextField = true
          }

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

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

      default:
        break
    }

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Remove `unique: true` from the hasMany text field.
  2. Enforce uniqueness of array members with a custom validate hook on the field.
  3. Use `index: true` if you need lookup performance without uniqueness.

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

const isHasManyText = (f) => f.type === 'text' && !!f.hasMany

Prevention

When it happens

Trigger: Defining `{ name: 'tags', type: 'text', hasMany: true, unique: true }`.

Common situations: Treating a hasMany text field like a set and expecting DB-level uniqueness enforcement; migrating a Mongo schema where unique arrays were tolerated.

Related errors


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