TypeError: Cannot read properties of undefined (reading 'id')

default discord avatar
KasparTr
last month
13

I have recently started seeing these errors throughout my LocalAPI implementation.



Here is the code which worked before, no changes.



File: src/core/payload/localApi/intex.ts


import payload, { Payload } from "payload";
const updateCollectionNoUser = async (collectionName, itemId, itemUpdate) => {
    try {
        await payload.update({
            collection: collectionName,
            id: itemId,
            data: itemUpdate,
            depth: 2,
            locale: 'en',
            showHiddenFields: true,
            overrideAccess: true,
        })
        return true
    } catch (error) {
        console.error("LocalApi | updateCollectionNoUser > error: ", error)
        return false
    }
}


I print out payload object and the 3 arguments, they are normal (not undefined or malformed).


I double checked DB and the item exists.



I don't understand this error, what exactly has changed or whats missing?


 TypeError: Cannot read properties of undefined (reading 'id') 


Callstack

Collection > CollectionBeforeOperationHook > myCustom.ts > LocalApi

  • default discord avatar
    Tinouti
    last month

    Looks similar to my issue (

    https://discord.com/channels/967097582721572934/1092554852976033792/1092554852976033792

    ), might be connected?



    Did you use the

    payload generate:types

    command recently by any chance? 🤔

  • default discord avatar
    KasparTr
    last month

    I did yes. How did you manage to solve this?

  • default discord avatar
    Tinouti
    last month

    I didn't yet 🥲

  • default discord avatar
    Exo
    last month

    @KasparTr @Tinouti could you provide a minimal working example with the error?

  • default discord avatar
    Tinouti
    last month

    Error doesn't happen on a fresh install (I've got some code snippets in the other thread). I'm gonna try to see if I can repro this error on a fresh install using the generate types command.

  • default discord avatar
    Exo
    last month

    my first guess is that you are somehow depending on the

    id

    or

    document

    properties, those are not always available in

    beforeOperation

    hooks because the user might not actually have access to the document



    sadly I have to get to work now and won't have much time to look into it until after work



    https://payloadcms.com/docs/access-control/overview#argument-availability

    This is true for access control at least, not sure if it also is true for field/collection level hooks

  • default discord avatar
    Tinouti
    last month

    Hmm I don't think that this is it, I'm using these properties right before that

    update

    for a

    findById

    which is working fine. Also the same code works on a fresh install, hence my "messed up GeneratedTypes" theory. 🤔

  • default discord avatar
    KasparTr
    last month

    I would separate hooks from this issue as what reaches the payload.update function is ID and update body. Both are defined. It's not the issue of the hook.


    Payload object itself is defined, ID and update body is defined but the payload.update function return the error.



     TypeError: Cannot read properties of undefined (reading 'id') 


    UPDATE WITH SOLUTION
    But not root cause.

    When I print out payload.collections right before calling payload.update, I get the following showing that payload object is defined and that the collection "assets" exists.


    console.log("payload.collections: ", payload.collections)
    /* logs:
    ...
    assets: {
        Model: Model { assets },
        config: {
          access: [Object],
          timestamps: true,
          admin: [Object],
          fields: [Array],
          ...
        },
        graphQL: {
          ...
        }
      },
    ...
    */

    As this might be related, I am creating custom IDs for the Assets in the CollectionBeforeOperationHook as follows:


    if (operation == OPERATION_CREATE) args.data.id = generateRandomId(args.data)


    I then revisited my Assets Collection and just for the kicks (I'm really shooting in the dark here) commented out the following code.


        // {
        //   name: 'id',
        //   type: 'text',
        //   admin: {
        //     readOnly: true
        //   },
        // },


    I then tested again and now got a different, but similar error.


    TypeError: Cannot read properties of **null** (reading '_id')

    Notice the null vs undefined.



    SOLUTION


    I ended up dropping the assets and versions collection in the DB and things seem to work well, couldn't reproduce anymore.


    Hint: DB related. @Tinouti



    PROBLEM 2:


    How to roll this out to production without losing data 😬

  • default discord avatar
    Tinouti
    last month

    Oooh interesting, I did remove a field and added a new one not long ago without doing any db migration or anything, so you might be onto something! 👍

  • default discord avatar
    KasparTr
    4 weeks ago

    This problem returned. What is more, I cannot no longer select the collection item from the list (will be stuck in loading) and cannot be selected from another collection as a referenced items (an error occurred message is shown). The item in question is clearly in the database and there are no errors in console or payload log when reading it. Only the LocalAPI fails with the undefined error when the item is being updated.



    After further investigation I noticed the following in the logs (when I get the original "undefined" error).



    Object.condition...



    So I replaced the a field condition of one of the collections collapsible fields and the undefined issue was resolved.


    BEFORE (erroneous)


     
    label: 'Close position (caution!)',
    type: 'collapsible', // required
    admin: {
        initCollapsed: true,
        position: 'sidebar',
        condition: (data, siblingData) => {
          if (data.id && **data.assetType.includes(AssetType.PROPERTY)**) return true; // show after asset is created
          else return false;
        }
    }


    AFTER (error goes away)


    label: 'Close position (caution!)',
    type: 'collapsible', // required
    admin: {
        initCollapsed: true,
        position: 'sidebar',
        condition: (data, siblingData) => {
          if (data.id) return true; // show after asset is created
          else return false;
        }
    },


    Note that I used the problematic

    data.assetType.includes(AssetType.PROPERTY)

    in other field conditions without any issues.



    What we are seeing is a field condition (readonly) affecting write operations of a collection item. 🙈

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.