Not long ago I was working away with the term store though Powershell. I had to remove all of a particular group’s termsets and to do this I ended up calling the Group’s delete function. It appeared to work just fine, until I later found that I was unable to import terms with GUID’s used previously. This is somewhat of a common problem that developers will come across if they are saving certain terms or termsets and trying to reimport while the others with the same ID still exist.
However, in this case, the entire term store was empty, until I realized that orphaned terms exist. For those of you who do not know the managed metadata service too well, orphaned terms will be created when deleting a term that was reused/pinned elsewhere. Because the original term that the ‘duplicates’ reference doesn’t exist anymore, the terms become orphans and they reside in the system group.
These orphaned terms get removed automatically when the duplicates are removed. Supposedly.
So why do I still have orphans?
There appears to be a bug when removing a group through code where in certain cases the orphans never seem to be checked whether or not the duplicates have all been cleaned up. Through code I had to remove termsets one by one, using the group.termsets property, then commit. It seems that trying to do everything in one commit can cause this.
As far as removing the orphaned terms go, I was unable to actually target these terms through code as I would have the following error:
This operation is invalid in the Orphaned Terms term set.
Unfortunately I believe this leaves the MMS in a slightly corrupt state, it will still function so long as those GUID’s for the orphans are never used again. I ended up starting fresh because I fortunately ran into this before the code left the development server.
I wish I could say more about this issue after the fact however this is all I can say for the time being. If you really need to remove these orphans, an idea I had a the time was to create a duplicate of that orphan through code, then remove manually though the interface and see if that causes some sort of event receiver to run through and clear the source term (orphan).