Recently I had a bug raised on an EPiServer build which described an error message I’d never seen before. When attempting to assigned new group rights to a particular branch of the page tree, the admin user was faced with this error message:
After reflecting the code out I found the error message in a catch block around a database transaction. To understand what was happening, it’s necessary to have a bit of knowledge about how EPiServer manages its access rights.
What lies beneath
This table keeps track of user/group access rights. It contains records for each user and group stored against a page id. Crucially, the page id has a constraint on it – the page must exist in tblPage. This was the underlying cause of the error message – a non-existent page id was being inserted into the table. But how could that happen?
This table describes the page hierarchy. It records the page id of a page against the page id of its children, along with an integer indicating the level of nesting. When access rights for a branch of the pagetree are updated, two things happen:
1) The current rights for the user/group are removed from tblAccess. The records are deleted using a set of records from tblTree as a master list of pages included in the branch.
2) New rights for the user/group are assigned. These are written to tblAccess, again using a set of page ids obtained from tblTree. However, there is no constraint on tblTree. As a result, the table can contain a page id for a non-existent page. The upshot of this is that when tblAccess is updated, it attempts to write an invalid page id, which fails, resulting in the error message above.
This should never happen
Although tblTree should ideally have a constraint on it, the above scenario should never happen. Left to its own devices EPiServer will take care of its table structure, so the situation decsribed here looks like the result of a manual database manipulation. Someone, at some point, has hand-deleted some pages. This illustrates the pitfalls of directly manipulating CMS data nicely – table constraints will have led the way to deleting all references to the deleted pages, but tblTree has been missed. This is a lesson we should all know already, but it never hurts to be reminded why the lesson exists.