afterChange { doc } comes with an inner property id instead of the full document

default discord avatar
7 months ago

I have a collection called 'investments', and one of the properties is a 'project', which is a relationship. When I use the afterChange hook, in the doc parameter I'm receiving the project id instead of the full investment document. What could be the problem?


  • default discord avatar
    7 months ago

    I've been facing a similar problem recently. For me, it was that depending on whether I submit from the admin panel or the local api, I either receive the full doc or just the ID.

    It's because the admin panel uses depth 0 while local api uses depth 3. I wrote a workaround to handle all cases,

        if (!order.user?.id) {
            const user = await payload.findByID({
                collection: 'users',
                id: order.user
            returnObj.populated.user = user
        } else {
            returnObj.populated.user = order.user

    This creates a "populated" attribute that always contains the full doc data. since the order doesn't have an attribute with name "populated", it doesn't cause any issues. Idk if that's the prettiest solution but it works for me.

    Note that in my case, the user field is required, so I don't have to handle the case of order.user being undefined

  • default discord avatar
    7 months ago

    Thanks @sandrowegmann ! But in my case, the ID I'm receiving is not even the ID of the target document, it's actually an ID of a relationship from a property inside de document. So I can't even manually find it using the received ID

  • default discord avatar
    7 months ago

    So in an afterChange Hook of investments, you only receive the project ID and nothing else?

  • default discord avatar
    7 months ago



    I'm updating the payload to see if I manage to change that

  • default discord avatar
    7 months ago

    Any hooks before this one?

    What you return from a hook becomes the doc param in the next hook

  • default discord avatar
    7 months ago

    hmm, that sounds accurate

    let me check what I'm returning

    I have indeed a beforeChange

    oh looks like that's the problem, I'm just having a problem with the router here because of the update

    fixing that I'll check if it's working

    I appreciate the help

    apparently It could even be the afterDelete hook to be honest, that's the one that could send the project id

  • default discord avatar
    3 months ago

    @jarrod_not_jared this is closely related to our discussion yesterday (


    This is another place I think having parity between local api and admin dash could be important cc @jmikrut - if local api defaults to a depth of 2 on update operations, so should the admin dash

    As a workaround, for anyone else that ends up here I believe you can manually create parity with a beforeOperation hook

    beforeOperation: [
        ({ args, operation }) => {
            if (operation === 'update') {
                args.depth = 2;
            return args;

    JFYI this workaround creates some odd behavior
Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!


Connect with the Payload Community on Discord



Can't find what you're looking for?

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