payloadcms / payloadcms/payload

column "prefix" does not exist in media collection when using @payloadcms/storage-s3 with prefix option and Postgres migrations

Open
#12,475 9 comments 16 reactions 1 assignee View on GitHub

@denolfe is already working on this.

Since Mar 10, 2026.

Bug stale
Dominant language
TypeScript
Stars
44.8k
Forks
4.2k
Avg merge
2d 21h
Merged PRs (30d)
53

Description

Describe the Bug

When using the @payloadcms/storage-s3 plugin with a prefix configured for a media collection (e.g., media), and deploying to an environment that uses database migrations (like Vercel with Supabase/Postgres, or a local production-like setup), a runtime error column "prefix" does not exist occurs. This error typically happens during operations on the media collection, such as seeding (specifically when attempting to delete existing media).

The issue seems to stem from a discrepancy:

The prefix option in the s3Storage plugin configuration (e.g., collections: { media: { prefix: 'media' } }) leads to the generated payload-types.ts including prefix?: string | null; as an optional field in the Media interface.

However, the database migration files generated by PayloadCMS do not include a prefix column in the media table schema.
When PayloadCMS performs database operations, it appears to rely on the payload-types.ts definition, causing the ORM (db-postgres with Drizzle) to query for a prefix column that doesn't exist in the database schema when migrations are the source of truth.
This bug does not manifest in local development environments when NODE_ENV=development if payload db:push is used, likely because db:push synchronizes the schema (potentially creating the prefix column) based on the (plugin-influenced) payload-types.ts or derived config. However, the error surfaces when NODE_ENV=production or when relying strictly on migrations, as the prefix column is not part of the formal migration-defined schema.

Expected Behavior:
The prefix configuration within the S3 storage plugin should be used solely for determining the storage path in the S3 bucket. It should not:

  1. Cause a prefix field to be added to the Media collection's type definition in payload-types.ts unless explicitly defined as a custom field by the user in their collection config.
  2. Lead to the ORM attempting to query a prefix column in the database if that column is not defined in the migrations.
Link to the code that reproduces this issue

https://github.com/findmydoc-platform/website/blob/dc267ba0e7b937f558eef72c6cffa969dc459df3/src/plugins/index.ts#L113

Reproduction Steps
  1. Configure a new PayloadCMS project with @payloadcms/db-postgres and @payloadcms/storage-s3.
  2. Define a media collection similar to the one in src/collections/Media.ts (without a prefix field).
  3. In payload.config.ts, add the @payloadcms/storage-s3 plugin and configure a prefix for the media collection (e.g., prefix: 'media').
  4. Generate types: pnpm run payload generate:types. Observe that payload-types.ts now includes prefix?: string | null; in the Media interface.
  5. Create an initial migration: pnpm run payload migrate:create initial_schema. Inspect the migration SQL; it will not contain a prefix column for the media table.
  6. Run the migration against a clean Postgres database: pnpm run payload migrate.
  7. Set NODE_ENV=production.
  8. Attempt to seed the database or perform operations that involve querying or deleting from the media collection (e.g., using a seed script that clears collections, like the one in your src/endpoints/seed/index.ts which calls payload.db.deleteMany({ collection: 'media', ... })).
  9. Observe the error: ERROR (payload): column "prefix" does not exist.
Which area(s) are affected? (Select all that apply)

plugin: other, db-postgres

Environment Info
Binaries:
  Node: 23.10.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: 10.10.0
Relevant Packages:
  payload: 3.38.0
  next: 15.3.2
  @payloadcms/db-postgres: 3.38.0
  @payloadcms/email-nodemailer: 3.38.0
  @payloadcms/graphql: 3.38.0
  @payloadcms/live-preview: 3.38.0
  @payloadcms/live-preview-react: 3.38.0
  @payloadcms/next/utilities: 3.38.0
  @payloadcms/payload-cloud: 3.38.0
  @payloadcms/plugin-cloud-storage: 3.38.0
  @payloadcms/plugin-form-builder: 3.38.0
  @payloadcms/plugin-nested-docs: 3.38.0
  @payloadcms/plugin-redirects: 3.38.0
  @payloadcms/plugin-search: 3.38.0
  @payloadcms/plugin-seo: 3.38.0
  @payloadcms/richtext-lexical: 3.38.0
  @payloadcms/storage-s3: 3.38.0
  @payloadcms/translations: 3.38.0
  @payloadcms/ui/shared: 3.38.0
  react: 19.1.0
  react-dom: 19.1.0
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 8

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.