umbraco / Umbraco.Deploy.Issues

1 stars 0 forks source link

Better handling of Schema deployment issue "Could not find parent with id XXXX." #216

Closed hfloyd closed 1 month ago

hfloyd commented 4 months ago

I and colleagues have come across this frustrating error message when doing schema updates, and it doesn't provide any decent clues as to WHERE this mysterious id SHOULD be located. Is this a datataype? A content node?

I have noticed this especially on larger operations - such as pushing an entire version-upgraded site to a new Cloud account, or pulling down a site locally. I know with the interconnected nature of doctypes, datatypes, and content nodes (often serving as the "source" of a picker or MNTP), parsing out dependencies can be tricky, but it would be great if these sort of operations could handle things better - at least providing more contextual information in the error messages.


Incidentally, when I came across this today (upgrade of Umbraco 9 to 13, push to new Cloud account) It seems the actual issue blocking the deployment was that the standard "Member" member type had its GUID changed between versions (why? who knows!). I figured I could manage the "collision" by just changing my local one's alias to "MemberOld", and the collision message went away, to be replaced by the "Could not find parent with id ...." message. I was only able to resolve it when I exported the schema from the Cloud site, pulled it down, then exported my local on top of those UDAs (I didn't do a local schema import first because I didn't want to overwrite any of my customizations). When I then re-imported the schema locally, I got a more useful SQL server error about a duplicate GUID value in the property table. Using grepWin, I searched for that GUID across all the local UDA files, and found it was related to the stupid "Member" - though the top-level GUID had been changed, the property GUID had NOT been changed, thus my original "old" member was STILL conflicting with the updated Member. Fortunately for me, Members were not in use in this site, so I just deleted my local "old" Member type entirely, then the schema import was able to complete. When I pushed the deletion of that old Member type UDA to the Cloud site, then it was also able to complete the schema update.

ronaldbarendse commented 3 months ago

Hi Heather, this is a very frustrating error indeed! The Could not find parent with id... error message can be thrown within Deploy (version 13) when getting the artifact and it has ParentId > 0, but can't find the required entity for:

The IDs are stored in the umbracoNode table and have a foreign key between the id and parentId columns, so all parent IDs require a row to exist. You can verify this by running the following SQL query against both current/remote environment databases and ensuring no results are returned (this can only happen in the odd case the foreign key doesn't exist though):

SELECT * FROM umbracoNode WHERE parentId NOT IN (SELECT id FROM umbracoNode);

The next thing to check is whether the ID that can't be found is actually in the database and what object type is has. Can you share the results of the following query of both current/remote environments (feel free to exclude the text column):

DECLARE @id int = 1084; -- Use the ID from the error message
SELECT * FROM umbracoNode WHERE id = @id OR parentId = @id;

If this returns any results, I can check whether the object type is of the expected type. Maybe this is incorrect or Deploy doesn't support the used parent type yet...


When the above doesn't provide any results, the more complex issue might be in the way the CMS publishes/handles notifications. Once a deployment has completed and the database transaction is completed, Deploy publishes the notifications (like DataTypeSavedNotification and ContentTypeSavedNotification) by grouping them per type and only invoking the handlers that implement IDistributedCacheNotificationHandler (see PR https://github.com/umbraco/Umbraco-CMS/pull/14332). This should prevent running user-defined notification handlers, but still ensure the distributed cache (like in-memory cache, NuCache content index, Examine indexes, etc.) keeps everything in-sync.

Sometimes though, these notifications contain entities that were in an intermediate state, like when updating a data type name and then moving it to a different parent. The first DataTypeSavedNotification would contain an outdated parent ID, while the DataTypeMovedNotification would have the correct one.

Deploy also uses these kind of notification handlers to write the UDA files to disk and update the signatures in the database: both actions require creating the artifact 🤔 It could be that one of these actions can't find the parent ID because it's using an outdated entity from a notification, although that seems unlikely, because Deploy doesn't delete items (so even if incorrect, it should still be able to find it) 🤯 A more likely scenario would be that some CMS services haven't cleared their repository cache yet (also done using the notification handlers) and the parent entity was created in the deployment that just completed.

Although we should probably rearchitect the way distributed caches are refreshed in the CMS (e.g. populating a state of required actions based on the notifications and executing them in a specific order, instead of based on individual notifications), I'll see if we can work-around this in Deploy:

ronaldbarendse commented 3 months ago

Oh and regarding the member type GUID: Deploy identifies identical entities based on the UDI (e.g. umb://member-type/{GUID}, but the CMS requires the alias or name to be unique. The default Member member type is created during installation and although newer versions now ensures all installations use the same GUID, older versions might not and manually removing the default one and re-adding it using the same name/alias will also result in different GUIDs.

If you don't use members, I'd recommend deleting the default member type and removing it from all environments. You can even prevent it from being created by the installer if you configure the install default data settings (which can be useful if you do a fresh clone of a Cloud project, as that will otherwise re-create it again).

hfloyd commented 1 month ago

Thanks for all the info, @ronaldbarendse. I guess the error message might not indicate an actual failure, but rather those notifications/caching, etc. Next time I see the issue I will try your SQL.

ronaldbarendse commented 1 month ago

Would be great to get some results from the SQL query if you encounter this again, thanks @hfloyd 🙌🏻

I've improved the exception messages with some more meaningful context (like when it occurs, e.g. getting or processing the artifact and included the UDI), which will be part of the upcoming v13 and v14 releases. I'll therefore close this issue now, but feel free to post more information here, so we can figure out what the actual root issue is 😄

hfloyd commented 1 month ago

Thanks! Having the UDI is helpful, since that includes the object type, which makes it easier to locate.

In this specific case the issue was the "Member" type, but there have been other cases. Hopefully others, if they encounter the issue themselves and search online will come across this thread and can use the SQL to troubleshoot, and add their own findings.