1. From the Zope bin directory (frequently /usr/local/zope/bin on UNIX machines), invoke zopectl: [user@machine bin]$ ./zopectl 2. From the zopectl prompt, stop your Zope instance: zopectl> stop 3. From the zopectl prompt, start the debugging interpreter: zopectl> debug 4. From the debug prompt, do a little bit of setup: >>> from Zope.Startup.run import configure >>> configure('/path/to/zope.conf') >>> from ZODB.POSException import POSKeyError For the second line above, put in the full filesystem path to your zope.conf file. For many Linux installations, this will be '/usr/local/zope/etc/zope.conf'. 5. Get at the Zope path for the container of the object that's throwing the POSKeyError: >>> obj=root.unrestrictedTraverse('/path/to/container') 6. Find the ID of the object that's causing the problem: >>> for id,val in obj.objectItems(): ... try: val.getId() ... except POSKeyError: break ... This should produce a list of all the objects in the containing folder stopping at the one that throws the POSKeyError exception. The id of that object will now be bound to the variable id. You can find the id of the cursed, evil, broken object: >>> id 'nameOfBrokenObject' 7. In the previous recipe, this is where we would have called the manage_delObjects method of the containing folder, but in solving my own POSKeyError, this didn't work any more. I'm sure someone more enlightened than I could tell you why, but I found (with much Googling) another way. In all frankness, the mystical workings of the following code are over my head, but it works. The gist is that it removes "the reference from the parent folder, without accessing the bad object." This gem was found in the following list thread: http://www.dzug.org/mailinglisten/zope-org-zope/archive/2004/2004-07/1090024676313 >>> obj._objects=tuple(filter(lambda i,n=id: i['id']!=n, obj._objects)) >>> delattr(obj,id) 8. Finally, you must commit the transactions to ZODB: >>> get_transaction().commit() 9. You can now exit from the debugger with Ctrl-D or exit: >>> exit 10. And restart your Zope instance: zopectl> start If your Zope instance doesn't restart cleanly, you may have more than one bad object, so you may need to repeat the above steps. 11. And quite out of zopectl: zopectl> exit N.B.: In more recent versions of Zope (beginning, I believe, with 2.9) you now need to handle step 8 differently: >>> import transaction >>> transaction.commit()