I came across an interesting issue generating a Sitecore Package recently. Googling the issue didn't give me the whole answer, so it's time to enhance the internet again with a explanation of what I saw and why I think it happened...
I was building a package as a backup before making some changes to a client's site. I added a series of "sources" to the package for some sets of items, but one final bit of the site did not work. The dialog accepted my choice of items and their children, but when I tried to close the dialog for adding a new source:
I got an error back instead of success:
Clicking the "details" button there got me a YSOD:
For Google's benefit, the interesting part of the stack trace for this was:
[ArgumentOutOfRangeException: startIndex cannot be larger than length of string. Parameter name: startIndex] System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) System.String.Substring(Int32 startIndex) +19 Sitecore.Install.Items.ItemFieldsProperties.GetFieldsProperties(Item item) +432 Sitecore.Install.Items.ItemToEntryConverter.InternalConvert(Item item, IProcessingContext context) Sitecore.Install.Framework.BaseConverter`1.Convert(T entry, IProcessingContext context) +69 Sitecore.Install.Framework.InternalSink.Put(T entry) +97
As a good developer I tried searching for that issue, and came up with only one interesting hit, in a pretty old blog post. That dates back to 2013 (!) and describes the same error I saw, but said that Sitecore Support said "this is your problem" when asked about it.
So useful to see that someone else saw the problem - but didn't help me specifically...
Given the stack trace didn't say much of help, the next step was to find out what the code was doing when the exception occurred. Breaking out ILSpy, the method being called there is this:
That code is going through all the fields on an item to make a pipe-separate list, and then finally it tries to remove the first pipe in order to return the list as a string. Maybe not the best way of achieving that behaviour, but we'll work with what we've got...
The obvious failure path here is "what happens if the item has no fields"? No data would be added to the
and hence an exception occurs when you try to skip the first character of the resultant empty string.
Next question then, is why do we have an item with no fields? Surely all items have some fields? They all inherit from the standard Sitecore base item, right? Well I did some snooping through the content tree to try and work out what was broken. Since the issue appeared making packages, I tried adding different subtrees of the content until I found the specific place in the tree which caused the issue:
That does indeed have no visible fields, but it doesn't show any obvious error. So the next logical thing to check is the template:
And there we have the issue - the template this item uses inherits from something that's missing! And that's where all the fields went, which in turn caused the crash.
I suspect something like this was the underlying cause of the bug in the blog post I found before, but it can be hard to find the dodgy item in a big content tree. Particularly because the issue only really revealed itself in the specific situation of packaging.
I'd recommend using a sort of "binary search" approach here. If packaging a specific item breaks, go down to its children and try to make packages of just each child. Work out which one (or ones) fail and which succeed. Doing that until you're confident which items fail, and which items succeed will help you to work out what item (or template used by items) is broken.
Those data templates - they're important...