Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 17, 2025

What?

PostgreSQL identifiers exceeding 63 characters cause migration failures when combining nested arrays, localization, and versioning. Names like _users_v_version_ingredient_sections_section_ingredients_locale_idx (68 chars) get silently truncated by PostgreSQL, breaking subsequent migrations that reference the full name.

Why?

Direct string concatenation in traverseFields.ts bypassed existing truncation utilities (buildIndexName, buildForeignKeyName), creating identifiers that exceeded the limit.

How?

Applied truncation helpers consistently across all index and foreign key name generation:

Array fields:

  • ${arrayTableName}_order_idxbuildIndexName({ name: ${arrayTableName}_order, adapter })
  • ${arrayTableName}_parent_id_fkbuildForeignKeyName({ name: ${arrayTableName}_parent_id, adapter })
  • Same for _locale indexes

Block fields:

  • Applied to _order, _parent_id, _path, and _locale indexes
  • Applied to _parent_id foreign keys

Select fields:

  • Applied to order, parent, locale, and value indexes
  • Applied to parent foreign keys

Helpers truncate to 60 chars (leaving room for suffixes like _idx, _fk and numbering for duplicates), ensuring compliance with PostgreSQL's 63-char limit.

Fixes #9649

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 127.0.0.11
  • 8.8.8.8
  • analytics.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • api.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • assets.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python -m localstack.runtime.main (dns block)
  • fastdl.mongodb.org
    • Triggering command: node ./postinstall.js (dns block)
  • localhost.localstack.cloud
    • Triggering command: /opt/code/localstack/.venv/bin/python /opt/code/localstack/.venv/bin/localstack status services --format=json (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Payload creates too long names/identifiers for postgress</issue_title>
<issue_description>### Describe the Bug

Given I use payload with a postgress database

When combining features like nested arrays, localization and versioning
Then payload creates too long index and table names like _users_v_version_ingredient_sections_section_ingredients_locale_idx
Then Postgress like Neon with Vercel then truncates this to use only the first 63 chars
And that creates all sorts of problems (I assume)

On my end this surfaced when I removed some of the features that created the long index
Thereby creating a migration dropping the index and altering tables
Which postgress takes only 63 chars of thereby failing.

Link to the code that reproduces this issue

https://github.com/Xiphe/payload-long-index-names

Reproduction Steps

  1. Check out the repo 👆
  2. Run pnpm install
  3. Connect with a postgress db
  4. Run pnpm payload migrate
  5. See this error
pnpm payload migrate

> postgress-id-limit@1.0.0 payload [...]/postgress-id-limit
> cross-env NODE_OPTIONS=--no-deprecation payload migrate

[20:43:29] WARN: No email adapter provided. Email will be written to console. More info at https://payloadcms.com/docs/email/overview.
[20:43:29] INFO: Reading migration files from [...]/postgress-id-limit/src/migrations
[20:43:29] INFO: Migrating: 20250412_183931
[20:43:29] ERROR: Error running migration 20250412_183931 relation "_users_v_version_ingredient_sections_section_ingredients_locale" does not exist.
    err: {
      "type": "DatabaseError",
      "message": "relation \"_users_v_version_ingredient_sections_section_ingredients_locale\" does not exist",
      "stack":
          error: relation "_users_v_version_ingredient_sections_section_ingredients_locale" does not exist
              at [...]/postgress-id-limit/node_modules/.pnpm/pg@8.11.3/node_modules/pg/lib/client.js:526:17
              at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
              at Object.up ([...]/postgress-id-limit/src/migrations/20250412_183931.ts:4:3)
              at runMigrationFile ([...]/postgress-id-limit/node_modules/.pnpm/@payloadcms+drizzle@3.33.0_@types+pg@8.10.2_@types+react@19.1.0_payload@3.33.0_graphql@_0a75b007319f798981d7c38cf55f021d/node_modules/@payloadcms/drizzle/src/migrate.ts:96:5)
              at Object.migrate ([...]/postgress-id-limit/node_modules/.pnpm/@payloadcms+drizzle@3.33.0_@types+pg@8.10.2_@types+react@19.1.0_payload@3.33.0_graphql@_0a75b007319f798981d7c38cf55f021d/node_modules/@payloadcms/drizzle/src/migrate.ts:83:5)
              at migrate ([...]/postgress-id-limit/node_modules/.pnpm/payload@3.33.0_graphql@16.10.0_typescript@5.7.3/node_modules/payload/src/bin/migrate.ts:87:7)
              at async start (file://[...]/postgress-id-limit/node_modules/.pnpm/payload@3.33.0_graphql@16.10.0_typescript@5.7.3/node_modules/payload/bin.js:30:7)
      "length": 562,
      "name": "error",
      "severity": "ERROR",
      "code": "42P01",
      "where": "SQL statement \"ALTER TABLE \"_users_v_version_ingredient_sections_section_ingredients_locales\" ADD CONSTRAINT \"_users_v_version_ingredient_sections_section_ingredients_locales_parent_id_fk\" FOREIGN KEY (\"_parent_id\") REFERENCES \"public\".\"_users_v_version_ingredient_sections_section_ingredients\"(\"id\") ON DELETE cascade ON UPDATE no action\"\nPL/pgSQL function inline_code_block line 2 at SQL statement",
      "file": "namespace.c",
      "line": "636",
      "routine": "RangeVarGetRelidExtended"
    }
 ELIFECYCLE  Command failed with exit code 1.

Which area(s) are affected? (Select all that apply)

db-postgres

Environment Info

Binaries:
  Node: 20.11.0
  npm: 10.2.4
  Yarn: N/A
  pnpm: 10.4.1
Relevant Packages:
  payload: 3.33.0
  next: 15.3.0
  @payloadcms/db-postgres: 3.33.0
  @payloadcms/email-nodemailer: 3.33.0
  @payloadcms/graphql: 3.33.0
  @payloadcms/next/utilities: 3.33.0
  @payloadcms/payload-cloud: 3.33.0
  @payloadcms/richtext-lexical: 3.33.0
  @payloadcms/translations: 3.33.0
  @payloadcms/ui/shared: 3.33.0
  react: 19.1.0
  react-dom: 19.1.0
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.1.0: Thu Oct 10 21:03:15 PDT 2024; root:xnu-112...

</details>

- Fixes payloadcms/payload#12094

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

…fier limits

Co-authored-by: DanRibbens <6434612+DanRibbens@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix long index and table names in Payload for Postgress fix(drizzle): truncate PostgreSQL identifiers exceeding 63-char limit Nov 17, 2025
Copilot AI requested a review from DanRibbens November 17, 2025 15:03
Copilot finished work on behalf of DanRibbens November 17, 2025 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants