After recently upgrading a site from Plone 3 to Plone 4 I noticed that when visiting the portal_view_customizations page was spitting an AttributeError.

Easily fixed I thought. Apparently not so.

I got there after a couple of hours digging in debug mode. Here's my solution:

The error I was getting form Plone was:

AttributeError: type object 'IThemeQPloneSkinLite' has no attribute 'isOrExtends'

This is a product that was already uninstalled. To fix the issue I had to place the original qPloneSkinLite product in the products directory.

Then start up a Zope debug session:

# ./bin/instance debug

Execute the following code, replacing PORTAL with the path to your Plone portal relative to the Zope root.

sm = app.PORTAL.getSiteManager()
adapters = sm.registeredAdapters()

for reg in adapters:
    if reg.name.find('qPloneSkinLite') >= 0:
    print 'Unregistering %s %s' % (reg.name, str(reg))
    if sm.unregisterAdapter(factory=reg.factory, required=reg.required, provided=reg.provided, name=reg.name):
        print 'Success'
    else:
        print 'Failure'

import transaction
transaction.commit()

The key is the reg.name.find('qPloneSkinLite') line. If your unwanted adapter is a different one you can view all the registered adapters by running

sm = app.PORTAL.getSiteManager()
adapters = sm.registeredAdapters()

for reg in adapters:
    print reg 

Remember to remove the offending product code from your products directory afterwards!

Worked for me! :)