Hi! I’m encountering a bug on a live client site where multiple different pages have apparently been assigned identical UUIDs, which leads to pages fields not working properly. Is this a known bug? Do you have any idea what might have been the cause of this error and what steps I can take to fix it?
The site has been running on Kirby 4.6.1. I’m now updating to the most recent version. As a quick fix I’m temporarily changing the pages field to store IDs instead of UUIDs.
All the best!
Edit: even with stored IDs the pages field seems to get confused and stores the ID of the wrong page.
Can you reproduce the issue in a Starterkit of the same Kirby version? Could it be that those duplicated UUID were created through page duplication? As far as I recall, that used to be an issue but not exactly sure which update fixed that, guess that was long before 4.6
Had same issue when on 4.4.1. Also some weird folders called “new” popping up when drafts where created.
The steps I took was
I had to update a custom custom plugin which made use of the uuid in a property. Might not apply to you but do a search for uuid in blueprints and plugins.
I changed this line: return $this->model()->uuid()->id();
To this return $this->model()->content()->get("uuid")->value();
update to 4.7
Clean the cache, including the uuid cache! On the live server I had to do that by ssh as ftp didn’t handle the big number of files very well
Finally you can force Kirby to regenerate the uuid cache in one go, there’s a method for that which I can’t recall at the moment
This script might help to identify duplicates and verify you don’t have any left after the remedy. Put it in a template. It’s originally based on something I found on this forum, should credit someone but it was a while ago so I don’t know who.
Interesting, thanks a lot for the hint. I’ve had the __new__ issue as well.
I’m actually using slug: "{{ site.time }}-{{page.title.slug}}" in a custom page creation dialog, but displaying the page’s UUID with text: "{{ page.permalink }}" in a text field in the sidebar. I’ll remove that field for now.
Thank you for this! Turns out there’s way more same UUIDs than I thought. I’ll clean the cache and regenerate UUIDs. The method is Uuids::generate('pages') (see Regenerate page uuids - #2 by texnixe)
Meanwhile I’ve upgraded Kirby to the latest version and removed the field where the UUID is shown to the user. Let’s see if the issue persists.
Depends on what you are trying to do here. Do you want to replace existing uuids for all articles? In that case my guess is that uuids are not regenerated if one already exists. (if it did replace existing, it would break any reference to that page in other content files).
In my case I Identified the duplicates which was just a couple of pages, and just removed the uuid from the content file. Kirby will generate a new uuid automatically when needed. Or you can call Uuid::generate like you did to speed that up I assume. Another way around it could be to loop your articles and call $article->save() instead, which (I think) also would generate a missing uuid.
To rebuild the uuid cache after deleting it, I think it is Uuid::populate() which you can run once if you like. I don’t think that is actually needed but may be good to do in a controlled manner to get everything up to speed.
Thanks for the answer! Yes, I’m trying to remove and regenerate UUIDs for all existing pages. There is only one place where the reference is needed in a pages field – which is broken anyways because of the many broken UUIDs – so I’m not concerned about references being lost.
There are hundreds of pages with duplicate/repeatedly assigned UUIDs, so manually removing from the content file is not really an option. I thought that updating the page using $page->update() would overwrite existing data in the content file but maybe that’s not the case with UUIDs?
To remove all uuids you can try this in your route:
foreach ($articles as $article) {
// Using save instead of update will be way faster than using update
$article-> save([
'uuid' => null,
]);
}
// Flush the uuid cache when all ids have been removed
Uuids::cache()->flush();
After clearing those uuids, you should be able to generate new uuids for the once you removed, in a loop like you did in your original code. Or even simpler, just call this once:
// Creates all **missing** uuids for all pages
Uuids::generate();
// Rebuild the cache
Uuids::populate()