13

I'm trying to find the item that has a bad internal link that is causing this exception when rebuilding the link database:

Job started: RebuildLinkDatabasesIndex|System.FormatException: Unrecognized Guid format. Actual value: ---> 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.Data.ID..ctor(String id) --- End of inner exception stack trace --- at Sitecore.Data.ID..ctor(String id) at Sitecore.Xml.Xsl.LinkUrl.GetInternalUrl(Database database, String url, String itemID, String anchor, String queryString) at Sitecore.Xml.Xsl.LinkUrl.GetUrl(XmlField field, Database database) at Sitecore.Data.Fields.LinkField.get_InternalPath() at Sitecore.Data.Fields.LinkField.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.ItemLinks.GetAllLinks(Boolean allVersions) 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: )

I have also tried running RemoveBrokenLinks.aspx and it gives the same exception. I have also tried using the Clean up databases tool which doesn't fix the issue.

Please advise how I can find the item path or item ID?

Sitecore 8.2.6

2
  • did you upgrade your solution from a previous release? Apr 11, 2018 at 5:02
  • Yes, it does happen to be after an upgrade from 8.2.1 Apr 11, 2018 at 5:10

5 Answers 5

11

I was unable to find the culprit using Vlad's method, so I went down another path. I installed the Sitecore PowerShell Extensions Module and modified one of the built-in scripts - the "Broken Links Report" under /Content Reports/Reports/Content Audit. I added a Try { } Catch { } as follows:

Try {
   $brokenLinks = $item.Links.GetBrokenLinks($IncludeAllVersions)
} 
Catch { 
   Show-Alert $item.ID
}

This alerted the offending content item ID. It was then easy to find the problem field on the item and fix the link.

3
  • How did you fix the link once you found the item?
    – Michael
    Jun 18, 2020 at 14:02
  • There was a GeneralLink field with empty "id" attribute. I just cleared the field and selected the link target again. Jun 18, 2020 at 23:27
  • Thanks for responding!
    – Michael
    Jun 20, 2020 at 3:31
9

In Sitecore 8.2.1 the GeneralLink field allows to contain links with empty "id" attribute like :

<link text="Description" linktype="internal" class="" title="HomeAlt" target="" querystring="" id="" />

But in Sitecore 8.2.6 it does not allow you to have such links.

Based on this the check for null or empty value is not needed because this situation is not expected.

For this reason,it works in Sitecore 8.2.1 and fails in 8.2.6.

Please use Scan for Broken links and try to fix it manually this links.

enter image description here

1
  • Hi Vlad, there is nothing remaining in broken links, but if I choose "System items" then there are a few dozen. Is there a script I can use to display the culprit instead of fixing all these other issues? Apr 12, 2018 at 6:58
7

Quick note for anyone who may stumble upon this like I did. After experiencing this issue myself on 8.2.6 (and not having any luck with the other solutions listed here), I submitted a ticket with Sitecore Support and they informed me that this is a known bug:

For your latest exception when rebuild link database, it was identified this issue as a bug. To track the future status of this bug report, please use the reference number 203014.

They provided a link to a hotfix, which contains an updated Sitecore.Kernel.dll. Unfortunately this hotfix alone didn't fix the issue either. After a few more iterations back & forth with them, they sent a web form (code posted below) & this did the trick. Please read the feedback from support though:

The issue actually should be split into 2 sub problems.
a. Stop Sitecore generate broken links - it should be addressed by the provided hotfix
b. Fix the links, which are already broken. this step should be performed manually. Our team has tested the following solution.

  1. back up your master database
  2. deploy the attached fixlinks page along with its .cs file.
  3. open page in a browser and click go.
  4. wait for page to finish. It will print "status: idle " and output list of fixed link fields.
  5. try to rebuild links in master db again.

Do not apply the fix on the core database. If you believe that your core database is affected, then it will require another approach.

And here is the code for the web form.

FixLinks.aspx:

<%@ Page Language="C#" AutoEventWireup="true" Debug="true" CodeFile="FixLinks.aspx.cs" Inherits="layouts_FixLinks" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
  <head runat="server">
    <title></title>
  </head>
  <body>
    <form id="form1" runat="server">
      <div>
        <asp:Button ID="Button1" OnClick="Button1_Click" runat="server" Text="Go" />
      </div>
    </form>
  </body>
</html>

FixLinks.aspx.cs

using Sitecore.Data;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class layouts_FixLinks : System.Web.UI.Page
{
    static bool running = false;
    static List<string> results = new List<string>();
    static int num = 0;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (running)
        {
            this.Button1.Enabled = false;
            Response.Write("status: processing "+num + "<br/>");
            if (!Page.IsStartupScriptRegistered("refresh") && !IsPostBack)
            {
                string scriptBlock =
                   @"<script language=""JavaScript"">
               setTimeout(function(){window.location.reload(1);},5000);
               </script>";

                Page.RegisterStartupScript("refresh", scriptBlock);
            }
        }
        else
        {
            Response.Write("status: idle " +num+ "<br/>");
        }
        lock (results)
        {
            foreach (string s in results)
            {
                Response.Write(s + "<br/>");
            }
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        running = true;
        num = 0;
        Task.Run(()=>this.go());
        Response.Redirect(Request.RawUrl);
    }

    public void go()
    {
        try
        {
            using (new SecurityDisabler())
            {
                Database db = Database.GetDatabase("master");
                Item root = db.GetRootItem();
                Stack<Item> items = new Stack<Item>();
                items.Push(root);
                while (items.Count > 0)
                {
                    Item current = items.Pop();
                    foreach (Item specific in current.Versions.GetVersions(true))
                    {
                        foreach (Field f in specific.Fields)
                        {
                            if (f.Type== "General Link"||f.Type== "General Link with Search")
                            {
                                LinkField link = (LinkField)f;
                                if ( !string.IsNullOrEmpty(f.GetValue(false,false))&&!string.IsNullOrEmpty(link.GetAttribute("linktype")) &&link.IsInternal)
                                {
                                    string id = link.GetAttribute("id");
                                    ID target = Sitecore.Data.ID.Null;
                                    if (!Sitecore.Data.ID.TryParse(id, out target))
                                    {
                                        using (new EditContext(specific))
                                        {
                                            specific.Fields[link.InnerField.ID].Value = string.Empty;
                                        }
                                        lock (results)
                                        {
                                            results.Add(specific.Uri.ToString()+" - "+link.InnerField.Name);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    Interlocked.Increment(ref num);

                    foreach (Item child in current.Children)
                    {
                        items.Push(child);
                    }
                }
            }            
        }
        catch(Exception e)
        {
            lock (results)
            {
                results.Add(e.Message);
                results.Add(e.StackTrace);
            }
        }
        finally
        {
            running = false;
        }
    }
}

Hope this helps someone.

1
  • This fixed it for me, and it runs far faster than the PowerShell method on large sites with many languages and versions. Sep 13, 2022 at 18:53
6

Here is a complete script to detect all those errors:

Add-Type -AssemblyName Sitecore.Kernel


function Resolve-Error ($ErrorRecord=$Error[0])
{
   $ErrorRecord | Format-List * -Force
   $ErrorRecord.InvocationInfo |Format-List *
   $Exception = $ErrorRecord.Exception
   for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
   {   "$i" * 80
       $Exception |Format-List * -Force
   }
}

function Test-Fields($item) {
    $anyState = [Sitecore.Links.ItemLinkState]::Any

    $item.Fields.ReadAll()
    for ($j = 0; $j -lt $item.Fields.Count; $j++)
    {
        $field = $item.Fields[$j];
        if ($field -ne $null)
        {
            $field2 = [Sitecore.Data.Fields.FieldTypeManager]::GetField($field)
            if ($field2 -ne $null)
            {
                Try {
                    $linksValidationResult = New-Object -TypeName "Sitecore.Links.LinksValidationResult" -ArgumentList $field, $anyState
                    $field2.ValidateLinks($linksValidationResult);
                } 
                Catch { 
                   Write-Host "Error on item: $($item.ID). Field: $($field.Name). Path: $($item.Paths.FullPath). Language: $($item.Language.Name). Value: $($field.Value)"
                }
            }
        }
    }
}

function ExecOnPath($path) {
    Write-Host "Execute on: $path"

    Get-ChildItem -Path "master:$path" -Recurse -Language * | ForEach-Object { Test-Fields  $_ }
}

ExecOnPath -Path "/sitecore/content/Home"

Write-Host "Done!"

Most of the time is is just because the value of those fields is: If you want to fix it with this script you can just add the following code in the catch clause:

if($item[$field.Name] -eq '<link linktype="internal" />') {                
    $item.Editing.BeginEdit()
    $item[$field.Name] = ""
    $item.Editing.EndEdit()

    Write-Host "Fixed automatically!"
} else {
    Write-Host "Cannot fix it automatically..."
}
2
  • Thanks a lot! For me the problem was in external links with no ID set. e.g. <link linktype="internal" /> Nov 4, 2018 at 19:49
  • This was the only answer that worked for me. The accepted answer is plagued by the same issue as the Sitecore UI method.
    – jrap
    Feb 5, 2019 at 20:43
0

Thanks user2003035 for his solution. That script worked for me but with little modification. I've changed script to return also all versions of child item from this:

Get-ChildItem -Path "master:$path" -Recurse -Language * | ForEach-Object { Test-Fields  $_ }

to this:

Get-ChildItem -Path "master:$path" -Recurse -Language * -Version * | ForEach-Object { Test-Fields  $_ }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.