I ran across a site recently, were I have yet to determine if it’s a problem with the site (Corruption), or a bug with SPQuery, but came up with a workaround regardless. The problem manifested itself with the actual root folder coming back into the result set of the query. Thus recursion would happen until a Stack Overflow exception was thrown.
I thought I would at least share the workaround.
Notice the following sample code, and specifically the bold red part.
void TraverseListFolder(SPFolder folder)
// Get the collection of items from this folder
SPQuery qry = new SPQuery();
qry.Folder = folder;
SPWeb web = null;
web = folder.ParentWeb;
SPListItemCollection ic = web.Lists[folder.ParentListId].GetItems(qry);
foreach (SPListItem subitem in ic)
Console.WriteLine(“List item: “ + subitem.Name);
Console.WriteLine(“List item type: “ +
if (subitem.Folder != null)
if(0 == folder.ServerRelativeUrl.ToUpper().CompareTo(subitem.Folder.ServerRelativeUrl.ToUpper()))
catch (Exception e)
// Cleanup that nasty web reference.
if (web != null)
So, even though the Folder property of the SPQuery object was set to start the scope of the request, for some reason on this customers site, the root folder was also showing up in the resulting SPListItemCollection. The simple workaround was to simply compare the ServerRelativeUrl of the scoped folder, with the url of the folder in the collection. If they were the same, we don’t recursively call TraverseListFolder().