Showing posts with label Upgrade. Show all posts
Showing posts with label Upgrade. Show all posts

Monday, January 21, 2019

Improving the Sitecore Broken Links Removal Tool

Standard

Background

While working through an upgrade to Sitecore 9.1, I ran into a broken links issues that couldn't be resolved using Sitecore's standard Broken Links Removal tool.

While searching the internet, I was able to determine that I wasn't the only one that faced these types of issues.

In this post, I intend to walk you through the link problems that I ran into, and why I decided to create an updated Broken Links Removal tool to overcome the issues that the standard links removal tool wasn't able to resolve.

NOTE: The issues that I present in this post are not specific to version 9.1.  They exist in Sitecore versions going back to 8.x.


Exceptions after Upgrade Package Installation

After installing the 9.1 upgrade package and completing the post installation steps of rebuilding the links database and publishing, I discovered that lots of my site's pages started throwing the following exceptions:



The model item passed into the dictionary is of type 'Castle.Proxies.IGlassBaseProxy', but this dictionary requires a model item of type 'My Custom Model'.

During the solution upgrade, I had upgraded to Glass Mapper to version 5, so I thought that the issue could be related to this.  After digging in, I noticed that my items / pages that were throwing exceptions had broken links.  I determine this by turning on Broken Links using the Sitecore Gutter in the Content Editor.


Next, I attempted to run Broken Links Removal tool located at http://{your-sitecore-url}/sitecore/admin/RemoveBrokenLinks.aspx.

After it had run for several minutes, it threw the following exception:

ERROR Error looking up template field. Field id: {00000000-0000-0000-0000-000000000000}. Template id: {128ADD89-E6BC-4C54-82B4-A0915A56B0BD}
Exception: System.ArgumentException
Message: Null ids are not allowed.
Parameter name: fieldID
Source: Sitecore.Kernel
   at Sitecore.Diagnostics.Assert.ArgumentNotNullOrEmpty(ID argument, String argumentName)
   at Sitecore.Data.Templates.Template.DoGetField(ID fieldID, String fieldName, Stack`1 stack)
   at Sitecore.Data.Templates.Template.GetField(ID fieldID)

Digging In

I needed to understand why this exception was being thrown, and started down the path of decompiling Sitecore's assemblies.  My starting point for reviewing the code was Sitecore.sitecore.admin.RemoveBrokenLinks.cs which is the code behind for the Broken Links Removal page.

I took all the code and pasted it into my own ASPX page so that I could throw in a break point and debug what was going on.  After a lot of trial and error and a ton of logging,  I discovered that code that was throwing the error existed in the FixBrokenLinksInDatabase method on line 11 shown below:

If the Source Field ID / "itemLink.SourceFieldID" on line 11 is null (this is the field where it has determined that there is a broken link), the exception noted above will be thrown.

The Cause of the Null Source Field

During my investigation, I determined that the cause of this field being null was due to the item being created from a branch template that no longer existed.

To put this another way, the target item represented as the sourceItem in the code above (line 8), had a reference to a branch template that no longer existed, and the lookup for item was returning a null source field.

Through my code logging and Content Editor validation, I found that we had a massive amount of broken links caused by a developer deleting several EXM branch templates:



Stack Exchange and Sitecore Community uncovered some decent information regarding this type of issue, and how to solve it manually by running a SQL query:

https://community.sitecore.net/developers/f/8/t/1784

https://sitecore.stackexchange.com/questions/88/how-do-i-fix-a-broken-created-from-reference-when-the-branch-no-longer-exists/89

Now, to fix this problem automatically using the tool, I just needed to add a null check in the code, and also create a way to clean up the references to the invalid branch templates.

Improved Broken Links Tool

The outcome of my work was an improved Broken Links Removal tool that I call the "Broken Links Eraser".

The tool does everything that the Sitecore Broken Links Removal tool does, with the following improvements:

  • Detects and removes item references to branch templates that no longer exist.
  • Removes all invalid item field references to other items (inspects all fields that contain an id).
  • Allows you to target broken links using a target path, you don't have to run through every item in the target database. This is useful when working with large sets of content.
  • Has detailed logging while it is running and feedback after it has completed. 

The tool is built as a standalone ASPX page, so you can simply drop the file in your {webroot}/sitecore/admin folder to use it. No need to deploy assemblies and recycle app pools etc.


All updates were made using Sitecore's SqlDataApi, so the code is consistent with Sitecore's standards. The code is available on GitHub for you to download and modify as needed:



Final Thoughts

I hope that you find this tool useful in solving your broken link issues. Please feel free to add comments or contact me with any questions on either Sitecore Slack or Twitter.


Monday, April 2, 2018

SolrProvider SolrSearchFieldConfiguration Error After Upgrade from Sitecore 8.1 Update-3 to 8.2 Update-6

Standard

Background

In a previous post, I wrote about upgrading an existing client's large, multisite 8.1 rev. 160519 (8.1 Update-3) instance to 8.2 rev. 171121 (8.2 Update-6).

After multiple rounds of testing, I deployed the upgraded instance to our client's Staging server (Windows Server 2008 R2). When navigating to the Content Editor, I ran into the following Solr related error:

Unable to cast object of type 'System.Collections.Concurrent.ConcurrentBag`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]' to type 'System.Collections.Generic.IReadOnlyCollection`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidCastException: Unable to cast object of type 'System.Collections.Concurrent.ConcurrentBag`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]' to type 'System.Collections.Generic.IReadOnlyCollection`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]'.



Digging In

After reviewing the stack trace and decompiling the Sitecore.ContentSearch.SolrProvider.dll , I focused on the SolrFieldNameTranslator.StripKnownExtensions method in the SolrFieldNameTranslator class:

1:  public string StripKnownExtensions(string fieldName)  
2:    {  
3:     fieldName = this.StripKnownCultures(fieldName);  
4:     foreach (SolrSearchFieldConfiguration availableType in (IEnumerable<SolrSearchFieldConfiguration>) this.fieldMap.GetAvailableTypes())  
5:     {  
6:      if (fieldName.StartsWith("_", StringComparison.Ordinal))  
7:      {  
8:       if (!fieldName.StartsWith("__", StringComparison.Ordinal))  
9:        break;  
10:      }  
11:      string str = availableType.FieldNameFormat.Replace("{0}", string.Empty);  
12:      if (fieldName.EndsWith(str, StringComparison.Ordinal))  
13:       fieldName = fieldName.Substring(0, fieldName.Length - str.Length);  
14:      if (fieldName.StartsWith(str, StringComparison.Ordinal))  
15:       fieldName = fieldName.Substring(str.Length, fieldName.Length);  
16:     }  
17:     return fieldName;  
18:    }  
Looking at line 4 above, the GetAvailableTypes method is shown below:

  private readonly ConcurrentBag<SolrSearchFieldConfiguration> availableTypes = new ConcurrentBag<SolrSearchFieldConfiguration>();  
   
  public IReadOnlyCollection<SolrSearchFieldConfiguration> GetAvailableTypes()  
   {  
    return (IReadOnlyCollection<SolrSearchFieldConfiguration>) this.availableTypes;  
   }  
   

As you can see in the code, when calling the GetAvailableTypes method, it casts the ConcurrentBag<SolrSearchFieldConfiguration> type to IReadOnlyCollection<SolrSearchFieldConfiguration> and this is where the "Unable to cast object" error message came from:

Unable to cast object of type 'System.Collections.Concurrent.ConcurrentBag`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]' to type 'System.Collections.Generic.IReadOnlyCollection`1[Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration]'.


Troubleshooting

According to docs.microsoft.com, the ConcurrentBag<T> class implements IReadOnlyCollection<T> interface in .NET Framework 4.5 and above. However, according to MSDN, in .NET Framework 4.0 it doesn't implement the IReadOnlyCollection<T> interface. The IReadOnlyCollection<T> interface was introduced in .NET Framework 4.5.

I went ahead and verified that the .NET Framework 4.5.2 was installed on the server. Next I checked my Web.config, and confirmed that the compilation targetFramework was set to "4.5.2" and that my httpRuntime targetFramework was set to "4.5.2":

<configuration>
  <system.web>
    <compilation targetFramework="4.5.2"/>
    <httpRuntime targetFramework="4.5.2"/>
  </system.web>
</configuration>

I then tried to repair the .NET framework, and even rebooted the server after the repair, and it didn't solve the problem.

Microsoft Security Update Woes

It was obvious that my 2 initial assumptions about not having the .NET Framework 4.5.2 installed or having a configuration issue were wrong.

As it turned out, .NET 4.5.2 did in fact contain the System.Collections.Concurrent.ConcurrentBag<T> class from System.dll which implemented the IReadOnlyCollection<T> interface, but there were a series of security updates that were rolled out by Microsoft, where the ConcurrentBag<T> did not implement the IReadOnlyCollection<T>. The security updates were built based on .NET framework 4.0 which did not have IReadOnlyCollection<T> interface at all.

In order to check whether one of the aforementioned security updates was installed, you could review the version of C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll

For the regular .NET framework 4.5.2 this version looks like 4.5.2... , but if a security update was installed it will look like 4.0.30319.36388.

The Final Solution - So Simple It Hurt

Upgrading the .NET framework to 4.6.1 solved this issue because we were back to having the System.Collections.Concurrent.ConcurrentBag<T> class from System.dll which implemented the IReadOnlyCollection<T> interface.




Monday, February 26, 2018

My Upgrade Experience from Sitecore 8.1 Update-3 to 8.2 Update-6

Standard
I was assigned the task of upgrading an existing client's large, multisite 8.1 rev. 160519 (8.1 Update-3) instance to 8.2 rev. 171121 (8.2 Update-6).  This particular client wasn't ready to go all the way to version 9.0, but will do so in the near future.

It took me longer than anticipated to get things up and running, simply because I needed to perform some updates to their custom solution.


Side Notes

The Sitecore solution that I was upgrading was using Castle Windsor as the Inversion of Control container along with Glass Mapper.

Getting Ready

To get started, I navigated over to the dev.sitecore.net site to arm myself with the files needed to perform the upgrade. The files that I downloaded from the site included:

  • Upgrade guide: Sitecore-8.2-Update-6-Upgrade-Guide.pdf
  • Sitecore update package: Sitecore 8.2 rev. 171121 (update package)
  • Configuration files for upgrade: Sitecore 8.2 rev. 171121 (config files)
  • Sitecore Update Installation Wizard: Sitecore Update Installation Wizard 2.0.2 rev. 170703
  • ZIP archive of the Sitecore site root folder: Sitecore 8.2 rev. 171121.zip

The software tools I use when performing upgrades are:

The road to 8.2 Update-6

These are the steps necessary to perform the upgrade:

Disabled xDB located in Sitecore instance \Website\App_Config\Include\Sitecore.Xdb.config
  • <setting name="Xdb.Enabled" value="false" />
  • <setting name="Xdb.Tracking.Enabled" value="false" />

The instance didn't have Email Experience and WFFM modules, so I didn't need disable their respective config files.

Ran the SQL database script called "CMS82_BeforeInstall.sql" located in \Sitecore 8.2 rev. 171121 (config files)\Database Upgrade Script on all Sitecore databases:
  • Core
  • Master
  • Web
  • Reporting (Analytics)

Installed the Sitecore Update Installation Wizard 2.0.2 rev. 170703.zip regular Sitecore package.

After it completed, I proceeded to install the "Sitecore 8.2 rev. 171121.update" update package using the installation wizard:  /sitecore/admin/UpdateInstallationWizard.aspx.

You will need to unzip the Sitecore 8.2 rev. 171121 (update package).zip in order to obtain the "update" file that Sitecore requires.


After clicking the "Analyze the package" button,  I opted NOT to install files as I preferred to start with a clean copy of the web root of Sitecore 8.2 Update-6.

I feel like this is a cleaner approach as it helps avoid having legacy cruft make its way into the new instance.


The package installation completed without any issues.

Instance Preparation and Comparing Files

I proceeded to stand up a clean version of Sitecore 8.2 Update-6 alongside my legacy 8.1 Update-3 instance and used the Beyond Compare app to compare the files. 

Apart from the Web.Config, the Sitecore.config was the next file where I saw the most differences.

Pro Tip: It is best practice is to move any differences that you find in vanilla config files to separate patch files. That way, life will be much easier for future upgrades.

Updating your Custom Solution

As some of the config files compared could exist in your custom solution, it is best to update the files in your solution as soon as you have completed your comparisons / merges on your Sitecore instance.

I worked in a new branch in source control, so that I could gradually update the files, and commit them as I made progress.

Sitecore 8.2 moved to .NET Framework version 4.5.2 from 4.5 in 8.1. So the target framework in each of the solution's projects needed to be updated:


NuGet Fun

The custom solution I was working with had all the Sitecore referenced assemblies in a single Nuget package, consumed via a custom feed. I opted to switch to the Sitecore public NuGet feed: https://doc.sitecore.net/sitecore_experience_platform/82/developing/developing_with_sitecore/sitecore_public_nuget_packages_faq

A lot of time was spent making sure the correct NuGet packages were loaded so that references where correct. As I was working with 8.2 rev. 171121, I matched my NuGet packages to the version by using the 8.2.171121, "NoReferences" packages.

As Jeremy Davis pointed out: "...the .NoReferences packages include the binary files but don’t have dependencies on other packages. So if you want to pick out individual DLLs without having to import all of the other assemblies that file depends on, choose these packages. It’s a bit more effort to manually add each of these that you need – but it means your project only refers to the specific files you want."

Note: When updating packages like WebGrease for example, it is important to match the assembly version in the Sitecore bin folder to the NuGet package versions.

Working with Solr

As I was using Solr as my search provider, I used Patrick's Powershell script to set my config files to use Solr.

The Sitecore instance was using the Single Instance Solr Configuration - Patch #391039, that I discussed in this post: http://sitecoreart.martinrayenglish.com/2016/09/bulletproofing-your-sitecore-solr-and.html

Support for Solr out-of-the box with this patch was added from Sitecore 8.2 Update-1 on, so I didn't have to include any configurations and files referencing this patch. Most of my work involved me changing my Solr index configurations

From:
Sitecore.Support.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.Support.391039

To:
Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrProvider

Example

From:
 <index id="my_custom_master_index" type="Sitecore.Support.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.Support.391039">

To:
 <index id="my_custom_master_index" type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex, Sitecore.ContentSearch.SolrProvider">

Bye Bye IsPageEditorEditing, Hello IsExperienceEditorEditing

As Darren mentioned in his post, Sitecore depreciated the variables IsPageEditor, and IsPageEditorEditing in Sitecore 8.0 Update 6, but kept the methods in all versions of 8.1. 

It would have been nice to have used the Obsolete attribute so that there wouldn't be such a surprise when upgrading to 8.2, and having all your usages of this method break your solution.

The fix was simple enough though. I performed a "find and replace" 

From:
Sitecore.Context.PageMode.IsPageEditorEditing

To:
Sitecore.Context.PageMode.IsExperienceEditorEditing

Problems with Castle Windsor

The solution I was working in was using Castle Windsor 3.3.0.51 and Castle Core 3.3.3.58. I opted to update Castle Windsor to version 4.1.0.0 and Castle Core 4.2.1.0 because I wanted the bug fixes and enhancements of the newer releases.

After deploying the updated assemblies to my upgraded Sitecore instance, I ran into the following error:

Could not load file or assembly 'Castle.Windsor, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

Castle Core changed the AssemblyVersion attribute to only include major version numbers so that they could avoid assembly binding errors with future releases/upgrades of Castle Core: https://github.com/castleproject/Core/issues/307

In my case, the error was happening because I had assemblies that were compiled against the new AssemblyVersion strategy.

Applying the following assembly binding redirects in my Web.config, fixed the issue.

<dependentAssembly>
        <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="4.0.0.0" />
</dependentAssembly>

<dependentAssembly>
        <assemblyIdentity name="Castle.Windsor" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="4.0.0.0" />
</dependentAssembly>

Minor Problem with Glass Mapper

Like Castle, I also opted to update Glass Mapper to a higher version. By doing so,  I ran into a small issue, similar to what is described here: https://github.com/mikeedwards83/Glass.Mapper/issues/244

In my case, I discovered that I was simply missing the Glass.Mapper.Sc.Mvc references to the new assembly in the MVC 52 folder in the Nuget package, and the updated assembly in my Sitecore bin folder.

Minor Problem with WebGrease

After making my way through the above-mentioned problems, I ran into a WebGrease version issue. 

Inner Exception: Could not load file or assembly 'WebGrease, Version=1.5.2.14234, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

The fix for this was to simply update my assembly binding redirect in the Web.config.

From:
<dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>

To:
<dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
      </dependentAssembly>

Let Me Hear You Say "Hallelujah"!

After I completed all these updates and fixes, I was presented with a beautiful new instance of Sitecore 8.2 Update-6 where my site loaded beautifully and my logs were clean.

Per Sitecore's upgrade guide, I completed the following final steps:
  • Cleared the browser cache. 
  • Published the site. 
  • Rebuilt the search indexes and the link database. 
  • Redeployed marketing definitions. 

I made sure to review my Sitecore logs after performing all of these tasks, and was happy to report that they stayed error free.

Saturday, February 7, 2015

My Upgrade Experience from Sitecore 7.5 to 8.0 Update-1

Standard
I was assigned the task of upgrading an existing client's large, multisite Sitecore 7.5 rev. 141003 instance to the shiny new Sitecore 8 rev.150121 (Update-1).  Having performed several version upgrades in the past, I estimated that it would take me about half a day to complete this process.

It took me a little longer than this to get them up and running, only because I ran into some issues with some legacy modules and because rebuilding the search indexes simply took forever!

I am still having a couple of issues after the upgrade that I noted in my Outstanding Issues section. I plan to keep this section updated as I receive feedback from the ticket I currently have open with Sitecore.

Solution for publishing error.
Solution for error when rebuilding links database.



Getting Ready

To get started, I navigated over to the new and improved dev.sitecore.net site to arm myself with the files needed to perform the upgrade. The files that I downloaded from the site included:

  1. 8.0 and 8.0 Update-1 upgrade packages
  2. 8.0 and 8.0 Update-1 config files for upgrade
  3. Upgrade guides for 8.0 and 8.0 Update-1
  4. Configuration file changes document for 8.0 and 8.0 Update-1
Note: You need to be logged into dev.sitecore.net for these links to work.

I must say, the Sitecore team did a fantastic job on the documentation for the upgrade!

The road to 8.0 initial release

The short version

These are the steps necessary to perform the upgrade:

  1. Run SQL Server update scripts on Core, Master and Web databases
  2. Run SQL Server script on Analytics database
  3. Remove PageEditorHanldeNoLayout Processor from web.config
  4. Remove PageLevelTestItemResolver from Analytics.config
  5. Turn Analytics off: Set Analytics.Enabled to false in Analytics.config
  6. Make sure any A/B or MV tests are disabled
  7. Disable WFFM and ECM config files if you have the modules installed
  8. Install the upgrade package using the Update Installation Wizard
  9. Apply the configuration file changes described in Sitecore Configuration File Changes document
  10. Revert the changes from step 5-7

Web.Config

The configuration file changes document for 8.0 scared me at first, because it was 30 pages! But, I quickly realized that in most cases, I could simple do a copy and replace on most of the files.

The document notes; "Most customers have only applied a small number of changes (if any) to the Web.config file. In that case, we recommend that you simply download the clean config file using the link above and re-apply any changes that you've made to save time and to reduce the risk of making mistakes when adding the new settings, pipelines, etc. to the file."

We inherited this site from another vendor who made their updates directly to the web.config, instead of using separate patch files. So unfortunately, the small number of changes didn't apply to our case. I was forced to manually update the web.config in 36 different locations!

Bump in the road

While installing the upgrade package, I received the following error:
Installation resulted in "The following errors occured during file installation: Access to the path '{instancepath}\Website\bin\System.Web.Http.dll' is denied."

For some reason, the assembly in question was marked as "read-only". I simply unchecked the "read-only" checkbox in the file's properties, ran the upgrade package again, and it worked like a champ.

Testing 8.0 initial release

After updating the databases via scripts, installing the update package, and making the necessary config changes, I was ready to boot up the new version.

At first, things looked good. The new login page came up and I was able to successfully get to the new SPEAK dashboard.

However, when I clicked on any the buttons on the dashboard, I received the following error:
Could not load type 'Sitecore.Shell.Applications.WebEdit.Commands.WebEditCommand' from assembly 'Sitecore.Client, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null'.

Experience told me that there had to be some custom module causing the issue. Knowing that this particular site was using a "patched" version of the old 6.5 calendar module, I disabled the config file straight away, tried again, but still didn't have any luck. Other modules that the site used that I tried to disable without success included:

  1. Sitemap XML
  2. Page Rate
I decided to make a backup of everything in my instance's include folder, and then I went back over to dev.sitecore.net and downloaded the zipped web root of the 8.0 initial release. I went ahead and removed everything that was in my instance's include folder, and then copied over all the files from the 8.0 zipped download's include folder.

This fixed my problem, and I was able to access all the areas of the platform. I also did a quick check in my log file, and it was error free.

Next, I loaded in the above-mentioned module's config files into my include folder. I kept my fingers and toes crossed, and to my delight, everything continued to work.

To 8.0 Update-1 and beyond

After getting the initial release up and running, I figured that upgrading to Update-1 would be a "walk in the park". It certainly was.

The short version

These are the steps necessary to perform the upgrade:

  1. Turn Analytics off: Set Analytics.Enabled to false in Analytics.config
  2. Disable WFFM and ECM config files if you have the modules installed
  3. Comment out the Sitecore.ContentTesting.Events.GenerateScreenshot,Sitecore.ContentTesting
    event handler in /App_Config/Include/ContentTesting/Sitecore.ContentTesting.config
  4. Install the upgrade package using the Update Installation Wizard
  5. Apply the configuration file changes described in Sitecore Configuration File Changes document
  6. Revert the changes from step 1-3
I was presently surprised to see that there was only 1 change to the web.config this time. As for the rest of the configuration files; I was able to simply do a copy and replace from the config files zip that I had previously downloaded.

Outstanding Issues

After doing some extensive testing, these are the following issues that are outstanding in our upgraded 8.0 Update-1 instance. 

I plan to keep this section updated with feedback from the ticket I currently have open with Sitecore.

Error when rebuilding the links database for Master and Web:

Job started: RebuildLinkDatabasesIndex|System.FormatException: Unrecognized Guid format.
   at System.Guid.GuidResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument, String failureArgumentName, Exception innerException)
   at System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
   at System.Guid..ctor(String g)
   at Sitecore.Analytics.Data.TrackingField.<>c__DisplayClass21.<get_Events>b__20(XElement e)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at Sitecore.Analytics.Data.TrackingField.ValidateLinks(LinksValidationResult result)
   at Sitecore.Links.ItemLinks.AddLinks(Field field, List`1 links, ItemLinkState linkState)
   at Sitecore.Links.ItemLinks.GetLinks(ItemLinkState linkState, Boolean allVersions, Boolean includeStandardValuesLinks)
   at Sitecore.Links.LinkDatabase.UpdateReferences(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.RebuildItem(Item item)
   at Sitecore.Links.LinkDatabase.Rebuild(Database database)
   at Sitecore.Shell.Applications.Dialogs.RebuildLinkDatabase.RebuildLinkDatabaseForm.Builder.Build()|Job ended: RebuildLinkDatabasesIndex (units processed: )


Resolution:

WFFM problem items were causing the errors.

Using SQL Profiler, we identified the problem items:

/sitecore/system/Modules/Web Forms for Marketers/Sample form
/sitecore/system/Modules/Web Forms for Marketers/Website
/sitecore/templates/Web Forms for Marketers/Form/_Standard Values

The site had the module installed but wasn't using it for anything. I think our client had intentions to start building some custom forms, but just never got around to doing it.

Knowing that we will be using it in the near future for a Dynamics CRM integration project, I went ahead and installed the latest version of the module, overwriting the problem items in the tree.

After doing this, I was able to successfully rebuild my links databases. Yay!

Error when publishing some items:

Job started: Publish to 'web'|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Could not resolve type name: Sitecore.Publishing.Pipelines.PublishVersion.Processors.Re
                                moveOtherVersions, Sitecore.Kernel (method: Sitecore.Configuration.Factory.CreateType(XmlNode configNode, String[] parameters, Boolean assert)).
   at Sitecore.Diagnostics.Error.Raise(String error, String method)
   at Sitecore.Configuration.Factory.CreateType(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.Factory.CreateFromTypeName(XmlNode configNode, String[] parameters, Boolean assert)
   at Sitecore.Configuration.Factory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)
   at Sitecore.Pipelines.CorePipelineFactory.GetObjectFromType(String type, XmlNode processorNode)
   at Sitecore.Pipelines.CoreProcessor.GetMethod(Object[] parameters)
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Publishing.PublishHelper.PublishVersionToTarget(Item sourceVersion, Item targetItem, Boolean targetCreated)
   at Sitecore.Publishing.Pipelines.PublishItem.PerformAction.ExecuteAction(PublishItemContext context)
   at Sitecore.Publishing.Pipelines.PublishItem.PerformAction.Process(PublishItemContext context)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Publishing.Pipelines.PublishItem.PublishItemPipeline.Run(PublishItemContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context)
   at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.Process(PublishContext context)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Publishing.Pipelines.Publish.PublishPipeline.Run(PublishContext context)
   at Sitecore.Publishing.Publisher.PublishWithResult()
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Jobs.Job.ThreadEntry(Object state)


Resolution:

Error in the web.config file:

       <publishVersion help="Processors should derive from Sitecore.Publishing.Pipelines.PublishItem.PublishVersionProcessor">
<processor
type="Sitecore.Publishing.Pipelines.PublishVersion.Processors.Re
moveOtherVersions, Sitecore.Kernel" />
</publishVersion>

You should concatenate the rows with the type name:

       <publishVersion help="Processors should derive from Sitecore.Publishing.Pipelines.PublishItem.PublishVersionProcessor">
<processor
type="Sitecore.Publishing.Pipelines.PublishVersion.Processors.RemoveOtherVersions, Sitecore.Kernel" />
</publishVersion>