Hey
@131537558453747712
Yeah, this is a good use case for an afterChange or a beforeChange collection hook.
afterChangeshould run after the data has been saved
For some reason it's complaining that the document does not yet exist.
Note that
documentand
document-chunkare two different collections
import { Document } from '@/payload-types'
import type { CollectionAfterChangeHook, CollectionConfig } from 'payload'
const afterChangeHook: CollectionAfterChangeHook<Document> = async ({ doc, req }) => {
await req.payload.create({
collection: 'document-chunk',
data: {
chunk: 'chunk2',
embedding: '[1,2,3,4,5,6,7,8,8,8]',
document: doc.id, // This complains that there's no document with this ID yet
},
req,
})
console.log('About to fetch chunks')
await req.payload.find({
collection: 'document-chunk',
where: {
document: {
equals: doc.id,
},
},
req,
})
}
export const Documents: CollectionConfig = {
slug: 'documents',
upload: {
staticDir: 'documents',
adminThumbnail: 'thumbnail',
mimeTypes: ['application/pdf'],
},
fields: [
{
name: 'alt',
type: 'text',
},
],
hooks: {
afterChange: [afterChangeHook],
},
}Can you try scoping it to the 'create' operation, there should definitely be an id there. Also your second req.payload.find operation there is redundant as the create operation will return the created document
document-chunkhas a relationship field set to
documentswith a field name of
document, correct?
I've had this happen before if I have any other hooks that are involved with the above collections (both collection-level and field-level) that don't have a
reqassigned to them.
Most recently it was a
beforeValidatehook without a
reqthat caused a very similar issue for me, make sure to check there.
Yes
Selectively including/excluding
reqcan create all sorts of nonsense
This is a completely new project
What are the odds that your issues go away if you remove the
reqfrom the
findI learnt that the hard way 😂
Oh man, I've been trying to find the root of this issue since beta - something
realweird happens. I have a PR for
plugin-searchfrom October that shows this
What are the odds that your issues go away if you remove the req from the find
Which is why I ponder the above
Yeah that straight up worked. Not sure what exactly I changed, cause initially I didn't pass
reqon either
Bingo
I've seen so many of these I actually have notes in my notebook on different scenarios. I have theories but nothing conclusive and have inspected the transaction code pretty intensely and am still not too sure. My leading theory is that if you follow the transaction, from the POV of that transaction that document has not been "comitted" or "created" yet so it fails to find it within the transaction itself.
If I remove the req from the create, it also breaks
The create necessarily needs that req
It must be there
But subsequent finds will fail if you include the req there. I can tell in advance that you're on Postgres by the way you describe how the calls fail
Interesting. So conceptually, by including
reqin the create, we simply add the creation to the transaction
Correct
But if you do a
findright after (with a
req), it will fail to find the doc
Hold up, but I still don't get why that
would necessarilybe required
Like why would it be required on the
createBecause everything up to that point is operating within a transaction
https://payloadcms.com/docs/database/transactions#async-hooks-with-transactionsTo be clear - you
don'thave to use a req but it is highly encouraged especially if you have other hooks or operations
In this particular case, a create with a req followed by a find with a req does something weird and fails, as you've observed
Well in this particular case, a create
withouta req followed by a find
withouta req also does something weird and fails
^ This is the scenario which confuses me
It's for sure just my own lack of knowledge of how Payload works. I'll do some more research to understand this better
Because that create is assuming that a doc.id exists but what I
thinkis happening is that the transaction, while saving the data, is not necessarily comitted yet
You can assume that the afterChange runs after the data is saved, but that transaction may not have been comitted yet if that makes sense
I need a deeper understanding of postgres to understand the difference between comitted transactions and data being saved 😅
Don't sweat it too much, just try to pass
reqwhere possible and be mindful of this caveat here. I like to think of transactions as isolated "paths" where there's a path outside the transaction, and inside the transaction. Read through the link I sent above too, ti should make things a bit more clear.
Otherwise I'll go ahead and mark this as solved if things started working for ya here!
Star
Discord
online
Get dedicated engineering support directly from the Payload team.