payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
29.15k stars 1.81k forks source link

TypeError: Cannot read properties of undefined (reading 'version') when trying to save a version #4788

Closed piraka9011 closed 9 months ago

piraka9011 commented 10 months ago

Link to reproduction

No response

Describe the Bug

When trying to save a new collection where versions and drafts are enabled i.e.

...
versions: {
    drafts: true,
},
...

then I cannot save/publish a new collection. I get a "Something went wrong" error in the UI (500) and the following logs:

[00:29:33] ERROR (payload): There was an error while saving a version for the Home Screen Card Announcement with ID 2.
[00:29:33] ERROR (payload): Cannot read properties of undefined (reading 'Symbol(drizzle:Columns)')
    err: {
      "type": "TypeError",
      "message": "Cannot read properties of undefined (reading 'Symbol(drizzle:Columns)')",
      "stack":
          TypeError: Cannot read properties of undefined (reading 'Symbol(drizzle:Columns)')
              at /Users/allabana/tarteel_ws/payload-cms/node_modules/src/pg-core/query-builders/insert.ts:53:27
              at Array.map (<anonymous>)
              at PgInsertBuilder.values (/Users/allabana/tarteel_ws/payload-cms/node_modules/src/pg-core/query-builders/insert.ts:51:31)
              at upsertRow (/Users/allabana/tarteel_ws/payload-cms/node_modules/@payloadcms/db-postgres/src/upsertRow/index.ts:274:36)
              at processTicksAndRejections (node:internal/process/task_queues:95:5)
              at Object.createVersion (/Users/allabana/tarteel_ws/payload-cms/node_modules/@payloadcms/db-postgres/src/createVersion.ts:27:18)
              at saveVersion (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/versions/saveVersion.ts:100:18)
              at create (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/collections/operations/create.ts:253:7)
              at createHandler (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/collections/requestHandlers/create.ts:26:17)
    }
[00:29:33] ERROR (payload): TypeError: Cannot read properties of undefined (reading 'version')
    at saveVersion (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/versions/saveVersion.ts:151:31)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at create (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/collections/operations/create.ts:253:7)
    at createHandler (/Users/allabana/tarteel_ws/payload-cms/node_modules/payload/src/collections/requestHandlers/create.ts:26:17)

I tried dropping all migrations and recreating them, but it still did not work.

To Reproduce

This is the collection we have defined. Note that versions was added after the collection was originally created. I tried this on both payload 2.0.0 and 2.7.0

import { CollectionConfig } from 'payload/types'

const HomeScreenCardAnnouncements: CollectionConfig = {
  slug: 'home-screen-card-announcements',
  admin: {
    useAsTitle: 'title',
  },
  versions: {
    drafts: true,
  },
  fields: [
    {
      type: 'row',
      fields: [
        {
          type: 'text',
          name: 'title',
          label: 'Title',
          localized: true,
          required: true,
        },
        {
          type: 'text',
          name: 'subtitle',
          label: 'Subtitle',
          localized: true,
          required: true,
        },
      ],
    },
    {
      type: 'row',
      fields: [
        {
          type: 'text',
          name: 'heading',
          label: 'Heading',
          localized: true,
        },
        {
          type: 'text',
          name: 'subheading',
          label: 'Subeading',
          localized: true,
        },
      ],
    },
    {
      type: 'row',
      fields: [
        {
          type: 'text',
          name: 'linkText',
          label: 'Link Text',
          localized: true,
        },
        {
          type: 'text',
          name: 'linkUrl',
          label: 'Link URL',
          validate: (val) => {
            try {
              new URL(val)
              return true
            } catch (_) {
              return 'Invalid URL'
            }
          },
        },
      ],
    },
    {
      type: 'upload',
      name: 'image',
      relationTo: 'images',
      admin: {
        description: 'Background image for the card. Should have a 1:1 ratio.',
      },
      filterOptions: {
        mimeType: { contains: 'image' },
      },
    },
    {
      type: 'row',
      fields: [
        {
          type: 'number',
          name: 'minimumMajorAppVersion',
          label: 'Minimum Major App Version',
          defaultValue: 0,
          min: 0,
          required: true,
        },
        {
          type: 'number',
          name: 'minimumMinorAppVersion',
          label: 'Minimum Minor App Version',
          defaultValue: 0,
          min: 0,
          required: true,
        },
        {
          type: 'number',
          name: 'minimumPatchAppVersion',
          label: 'Minimum Patch App Version',
          defaultValue: 0,
          min: 0,
          required: true,
        },
      ],
    },
    {
      type: 'row',
      fields: [
        {
          type: 'number',
          name: 'priority',
          label: 'Priority',
          min: 0,
          defaultValue: 1,
          required: true,
          admin: {
            description: 'Cards will be shown in ascending priority (1, 2, 3, ...).',
          },
        },
      ],
    },
    {
      type: 'row',
      fields: [
        {
          type: 'date',
          name: 'activatedAt',
          label: 'Activated At',
          defaultValue: new Date().toISOString(),
          required: true,
          admin: {
            date: {
              pickerAppearance: 'dayAndTime',
              timeIntervals: 5,
            },
          },
        },
        {
          type: 'date',
          name: 'deactivatedAt',
          label: 'Deactivated At',
          admin: {
            date: {
              pickerAppearance: 'dayAndTime',
              timeIntervals: 5,
            },
          },
        },
      ],
    },
  ],
}

export default HomeScreenCardAnnouncements

Payload Version

2.7.0

Adapters and Plugins

db-postgres, bundler-webpack, plugin-cloud-storage

DanRibbens commented 10 months ago

Hi @piraka9011, What version of @payloadcms/db-postgres are you on? I believe this was fixed in that package already.

piraka9011 commented 10 months ago

I upgraded @payloadcms/db-postgres from 0.2.2 to 0.3.1

My full dependency list:

"dependencies": {
  "@payloadcms/bundler-webpack": "^1.0.5",
  "@payloadcms/db-postgres": "^0.3.1",
  "@payloadcms/plugin-cloud": "^2.0.0",
  "@payloadcms/plugin-cloud-storage": "^1.1.1",
  "@payloadcms/richtext-lexical": "^0.5.1",
  "cross-env": "^7.0.3",
  "dotenv": "^8.2.0",
  "express": "^4.17.1",
  "payload": "^2.7.0"
},
"devDependencies": {
  "@types/express": "^4.17.9",
  "copyfiles": "^2.4.1",
  "lint-staged": "^15.2.0",
  "nodemon": "^2.0.6",
  "prettier": "^3.1.1",
  "ts-node": "^9.1.1",
  "typescript": "^4.8.4"
},
"resolutions": {
  "jackspeak": "2.1.1"
}

I now get a bunch of webpack errors when running yarn dev (set as cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon

The error is a few hundred lines so I just truncated to show the webpack build errors

yarn run v1.22.18
$ cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon
[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts
[nodemon] starting `ts-node src/server.ts -- -I`
[20:05:09] INFO (payload): Starting Payload...
[20:05:09] INFO (payload): Payload Admin URL: /admin
...
ERROR in ./node_modules/drizzle-kit/node_modules/minimatch/dist/mjs/unescape.d.ts.map 1:10
Module parse failed: Unexpected token (1:10)
...
ERROR in ./node_modules/hanji/readline.js 7:21-40
Module not found: Error: Can't resolve 'readline' in '/Users/allabana/tarteel_ws/payload-cms/node_modules/hanji'
Did you mean './readline'?
...
ERROR in node:zlib
Module build failed: UnhandledSchemeError: Reading from "node:zlib" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
...
webpack compiled with 124 errors and 152 warnings

I noticed db-postgres targets payload 2.0.0 https://github.com/payloadcms/payload/blob/main/packages/db-postgres/package.json#L39

Maybe that's the reason?

jamov commented 10 months ago

On my setup, after I add to CollectionConfig: versions: { drafts: true, }, All pages (created before this change) disappear from the pages list UI. Not sure if this is intended behaviour.

UPDATE: Another possibly related issue

Looking into the DB, the page XY versions remain there in the "_pages_versions" table. I suppose version from there is listed on the admin console, despite its parent entry no longer being present at the "pages" table.

denolfe commented 9 months ago

Note that versions was added after the collection was originally created.

This really is the crux of the issue. Changing a collection from unversioned to versioned or vice versa has some pretty large implications on storage data structure and querying of that data.

It sounds like we need to make this clearer in our documentation that making this change has these implications and the user should be expected to migrate some data to the new structure.

piraka9011 commented 9 months ago

the user should be expected to migrate some data to the new structure.

If this is even possible, adding an example would be very helpful! Otherwise, maybe you could recommend creating a new V2 of the existing collection and then migrating the data over from the old one.

denolfe commented 9 months ago

I think we're going to handle this on our end with a migration that can be pulled in. Just created a POC branch that we'll work off of: https://github.com/payloadcms/payload/tree/poc/feat-versions-migration.

Stay tuned. Closing this one, though.

benjick commented 8 months ago

Note that versions was added after the collection was originally created.

This really is the crux of the issue. Changing a collection from unversioned to versioned or vice versa has some pretty large implications on storage data structure and querying of that data.

It sounds like we need to make this clearer in our documentation that making this change has these implications and the user should be expected to migrate some data to the new structure.

From the docs:

Versions are extremely performant and totally opt-in. They don't change the shape of your data at all. All versions are stored in a separate Collection and can be turned on and off easily at your discretion.

So how do I get out of this? Just copy the https://github.com/payloadcms/payload/blob/63380dc3d946485002261904c99af78854bb993a/packages/payload/src/database/migrations/exampleVersionsMigration.ts into my migrations directory?

github-actions[bot] commented 2 months ago

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.