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
23.08k stars 1.43k forks source link

Example server fails when accessing /admin with `Error: Cannot read properties of undefined (reading 'createdAt')` #7126

Closed Aeolun closed 6 days ago

Aeolun commented 1 month ago

Link to reproduction

No response

Payload Version

3.0.0-beta.60

Node Version

v20.12.2

Next.js Version

15.0.0-rc.0

Describe the Bug

 ⨯ TypeError: Cannot read properties of undefined (reading 'createdAt')
    at Array.reduce (<anonymous>)
digest: "4292446021"
   8 |         } else {
   9 |             columns = [
> 10 |                 table[name]
     | ^
  11 |             ];
  12 |         }
  13 |         if (unique) return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1));
 ⨯ ../../node_modules/.pnpm/@payloadcms+db-postgres@3.0.0-beta.60_@opentelemetry+api@1.9.0_@types+pg@8.11.6_encoding@0.1._r3rnez2gugtepnwsxzywqkt5vy/node_modules/@payloadcms/db-postgres/dist/schema/createIndex.js (10:1) @ eval

I tried looking around a bit on whether I could find a fix to this, but I have hard time understanding where to even start. It's expecting some createdAt column that's not defined in the object, but the table creation logic is kind of... complex to say the least so no idea where it's supposed to come from.

Reproduction Steps

Using pnpm, run pnpx create-payload-app@beta cms

Enter information, most relevantly blank, postgresql and postgres://[username]@localhost:5432/cms (no password, not sure if relevant)

Then start the application with pnpm run dev, and access http://localhost:3000/admin.

Adapters and Plugins

@payloadcms/db-postgres 3.0.0-beta.60

yobottehg commented 1 month ago

I also had this issue yesterday locally when updating to beta 60 but not because of payload but because of updated drizzle-orm and drizzle-kit dependencies.

These versions worked for me:

    "drizzle-kit": "0.20.18",
    "drizzle-orm": "0.30.10",

I need these explicit dependencies because of some customs scripts i wrote to check that the migrations added in the PR will apply cleanly against the target branch.

Also note that beta59+ needs a newer Next.js version: https://github.com/payloadcms/payload-3.0-demo/blob/main/package.json#L32

GrowthWizard commented 1 month ago

I am running into the same issue, after trying to install the payload 3.0 beta.

npx create-payload-app@beta

  1. Choosing the website theme, using postgres + password on an empty database.
  2. During installation, running into the same issue, as reported here: https://github.com/payloadcms/payload/issues/6752
  3. Drizzle was not installed or mentioned in my package.json, using npm.
  4. Trying to install Drizzle manually: npm i drizzle-orm
  5. Ending up: with "drizzle-orm": "0.32.10",
  6. Running into a new issue: `✓ Starting... ✓ Ready in 2.4s ○ Compiling /admin/[[...segments]] ... ✓ Compiled /admin/[[...segments]] in 3.1s (4086 modules) ⨯ node_modules/@payloadcms/db-postgres/dist/schema/createIndex.js (10:1) @ eval ⨯ TypeError: Cannot read properties of undefined (reading 'createdAt') at Array.reduce () digest: "787331360" 8 | } else { 9 | columns = [

    10 | table[name] | ^ 11 | ]; 12 | } 13 | if (unique) return uniqueIndex(${tableName}_${columnName}_idx).on(columns[0], ...columns.slice(1)); GET /admin 500 in 5183ms `

  7. Using @yobottehg mention, of changing "drizzle-orm": "0.30.10" vianpm install --legacy-peer-deps`
  8. PostGres Connection does work now.
r1tsuu commented 6 days ago

Hey you all

If you want to use drizzle dependency directly, ensure that it has the same version as our drizzle package uses so you won't end up with 2 drizzle instances. https://github.com/payloadcms/payload/blob/ee3d5856e3749ea72372430142f00f6fd5657096/packages/drizzle/package.json#L49 - currently 0.32.1 That applies to other dependencies like pg https://github.com/payloadcms/payload/blob/ee3d5856e3749ea72372430142f00f6fd5657096/packages/db-postgres/package.json#L54

So this in your package.json should work.

"drizzle-orm": "0.32.1",

If using npm, generally with the beta you always want to use --legacy-peer-deps, or .npmrc file:

legacy-peer-deps=true

pnpm should work fine, to generate a project with it use: pnpx create-payload-app@beta --use-pnpm

Let me know here if something isn't clear, closing.

haythaminteractivelifelb commented 4 days ago

I'm on Beta-96 and I added 2 date fields as following:

    {
      name: 'ccpp_consent_date',
      type: 'date',
      admin: {
        date: {
          displayFormat: 'dd/MM/yyyy H:mm:ss',
          pickerAppearance: 'dayAndTime',
        },
        position: 'sidebar',
      },
      label: 'City Contact Privacy Policy Consent Date',
    },
    {
      name: 'tc_consent_date',
      type: 'date',
      admin: {
        date: {
          displayFormat: 'dd/MM/yyyy H:mm:ss',
          pickerAppearance: 'dayAndTime',
        },
        position: 'sidebar',
      },
      label: 'Terms and Conditions Consent Date',
    }

I can set save the values only the first time, but on update it always give me this error:

error: invalid input syntax for type timestamp with time zone: "{}"
    at eval (webpack-internal:///(rsc)/./node_modules/pg-pool/index.js:45:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async eval (webpack-internal:///(rsc)/./node_modules/drizzle-orm/node-postgres/session.js:60:22)

the error appears even when I'm trying to update from the admin UI and from the API! here's my API Update:

      await payload.update({
        id: selectedUser.id,
        collection: 'users',
        data: {
          ccpp_consent_date: new Date().toISOString(),
          tc_consent_date:  new Date().toISOString()
        },
      })

this issue appeared to me first when I moved to postgres Database specifically with the Dates fields like CreatedAt and UpdatedAt, I did a work around to fix it by adding a hook into all collections like this:

import type { CollectionBeforeChangeHook } from 'payload'

export const setTimestamps: CollectionBeforeChangeHook<any> = ({ data, collection }) => {
  const currentDate = new Date().toISOString()
  if (!data.createdAt) {
    data.createdAt = currentDate
  } else if (typeof data.createdAt !== 'string' && !(data.createdAt instanceof Date)) {
    data.createdAt = currentDate
  }

  if (!data.updatedAt) {
    data.updatedAt = currentDate
  } else if (typeof data.updatedAt !== 'string' && !(data.updatedAt instanceof Date)) {
    data.updatedAt = currentDate
  }
}

However Now it's happening with me when a user reset his password and there's a value in the resetPasswordExpiration field!

r1tsuu commented 4 days ago

@haythaminteractivelifelb

Looks like a different issue! Please, open a new one with reproduction.