Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from: https://blog.jermdavis.dev/posts/2023/sitecore-preview-database-crash

Fixing a broken preview database

When the instructions you're given don't quite cut it...

Published 17 July 2023

A colleague pointed me at an interesting issue recently, where trying to switch the Sitecore Desktop to view a "preview" database for a Publishing Target on a client's website caused a crash. The reason for this appears to be an interesting issue it would be fairly easy for others to trip over, so this seemed a useful thing to write up:

The issue url copied!

My colleague was looking at a local development instance for a client's website. The client had a Sitecore v10.2 site which had originally been installed as v9, and had been through a few upgrade cycles. The development instance had been set up following a series of steps documented in the project's wiki, and it appeared to be working fine. Part of the config and setup of the instance added a Preview publishing target, but until this point none of the developers involved had actually tried to use that...

What my colleague spotted was that when you clicked the Sitecore Desktop menu to change Content Editor to show this extra publishing target, you got a YSOD rather than Content Editor:

An ASP.Net crash screen, showing the stack trace below this image

For Google's benefit, the important part of the stack trace here is:

[ArgumentNullException: Value cannot be null.
Parameter name: item]
   Sitecore.Diagnostics.Assert.ArgumentNotNull(Object argument, String argumentName) +63
   Sitecore.Data.Managers.ItemProvider.ApplySecurity(Item item, SecurityCheck securityCheck) +33
   Sitecore.Data.Managers.DefaultItemManager.GetRootItem(Language language, Version version, Database database) +110
   Sitecore.Nexus.Data.DataCommands.ResolvePathCommand.ResolvePath(String itemPath, Database database) +134
   Sitecore.Nexus.Data.DataCommands.ResolvePathCommand.Execute(String itemPath, Database database) +513
   Sitecore.Data.Engines.EngineCommand`2.Execute() +93
   Sitecore.Data.Managers.ItemProvider.GetItem(String itemPath, Language language, Version version, Database database, SecurityCheck securityCheck) +149
   Sitecore.Pipelines.ItemProvider.GetItem.GetLanguageFallbackItem.Process(GetItemArgs args) +178
   (Object , Object ) +14
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +1268
   Sitecore.Data.Managers.DefaultItemManager.GetItem(String itemPath, Language language, Version version, Database database, SecurityCheck securityCheck) +305
   Sitecore.Data.Managers.DefaultItemManager.GetItem(String itemPath, Language language, Version version, Database database) +147
   Sitecore.Data.Managers.ItemManager.GetItem(String itemPath, Language language, Version version, Database database) +154
   Sitecore.Globalization.DictionaryDomain.GetDomainDefinitionItem(Database database, String name) +188
   Sitecore.Globalization.DictionaryDomain.TryParse(String domainDefinition, Database database, DictionaryDomain& domain) +416
   Sitecore.Globalization.DictionaryDomain.GetDefaultDomain(Database database) +134
   Sitecore.Pipelines.GetTranslation.TryGetFromContextDatabase.Process(GetTranslationArgs args) +149
   (Object , Object ) +9
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +1268
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) +236
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, Boolean failIfNotExists) +36
   Sitecore.Globalization.DefaultTranslate.TextByLanguage(String domainName, TranslateOptions options, String key, Language language, String defaultValue, Object[] parameters) +416
   Sitecore.Globalization.DefaultTranslate.TextByLanguage(String key, Language language, String defaultValue, Object[] parameters) +161
   Sitecore.Globalization.DefaultTranslate.TextByLanguage(String key, Language language, String defaultValue) +162
   Sitecore.Globalization.DefaultTranslate.TextByLanguage(String key, Language language) +150
   Sitecore.Web.UI.HtmlControls.Literal.set_Text(String value) +143

					

Another interesting oddity was that if you tried to publish some items from Master to Preview it would complete without errors in the UI. But no items would be published. Everything would get reported as "skipped" rather than published, no matter what publishing settings you picked...

The fix url copied!

The stack trace here didn't offer much of an immediate clue. It's a data-related error, and it appears to be something related to "Sitecore tried to find the root item for the database, but it failed". However it wasn't clear why. So I spent a chunk of time looking at the details of the instance's config to see if I could spot an issue.

None of the config looked wrong, but one thing did jog my memory as I stared at ShowConfig.aspx:

A screen grab of Sitecore XML config, showing the definition of a database, and its configured providers

After Sitecore v10.1, there's an extra database provider for "Items as Resources" (abbreviated to "IAR" fairly commonly). These are data files on your CM & CD roles which were introduced to make container deployment and update easier. I wrote about what's up here a while back when they first appeared.

So having seen this entry in the config, I thought I should check this file for the preview database. If the IAR files were missing that might explain this error. All the "default" items exist only in the IAR file now, rather than in the database. So if you didn't have that file that might well cause an "item can't be found" type error for a root item in a database. And when I went and checked out the filesystem, low-and-behold it didn't exist:

Windows Explorer showing the folders where Sitecore stores its IAR files, and the missing 'preview' folder

When I saw this I wasn't sure if this was an issue or not - but figured I should give it a try. So I copied the "web" folder and renamed it to match the "preview" database. (which meant changing "web" to "preview" on both the folder and the file inside it in this case) A new publishing target database should start from the basis of a web database in most cases, so that seemed like the right file to duplicate.

Having done that, I recycled the app pool for the website, and found that the YSOD was now gone and I could edit the preview DB fine. Publishing also now worked, and actually deployed items.

(Note that the recycle is important - it looks like the IAR files in these folders are only ever read on start up)

Success! url copied!

So how did we get to this state? A step missing from the developer setup instructions seems to be the cause. The SIF or SIA install process for Sitecore doesn't create a preview database - so you need some manual steps to add the extra database. The developer instructions in the project wiki covered adding the database and making sure you had the right connection string after doing a your base install, but did not mention the IAR folder.

I did do some googling after I'd worked out this fix (and hence the right keywords to use), which lead me to a Sitecore StackExchange answer saying pretty much the same thing - so I'm clearly not the only person who's hit this issue.

One thing I note is that if you Google creating a new Publishing Target, the default version of the docs you see is the v9 one which does not explain the issue with adding IAR files. You need to change to the 10.1 version or above to see that. So I suspect it would be fairly easy for people to miss this important difference in reality...

↑ Back to top