Solving broken brains


Need your advise, lately my Plone server keep having catalog brains issue, brain.getObject() keep giving me AttributeError...
I have to resolve by using collective.catalogcleanup and also do "clean and rebuild" catalog. (several times).

This is my Plone setup:

Using so that some of my objects subscribed to IObjectModifiedEvent can run asynchronous using zeo-worker for some of the object updates.

My question is in what way can plone_catalog gets out of sync or broken? Is it possible that reindexObject between async corrupt the index?


1 Like

Getting an inconsistent portal_catalog happens often - depending on Plone version, installed add-ons etc. or your own custom code. The reason is usally bad programming, programming errors jn particular in add-ons. Debugging such issues can be hard.

Concurrent operations should not cause any inconsistencies because of the ZODB isolation level.


Are you using collective.solr?
Did you find already out, what content types get lost?

Found the main bug, tested and give me bad brain.

## this will create bad brain
obj = portal['doc']
api.content.move(source=obj, target=another_folder)

Moving obj and reuse obj is a bad idea.

## reassign obj is important here
obj = api.content.move(source=obj, target=another_folder)

Hope this help for those with the same problem.

1 Like

For the record, even though the (base) object being moved is (by identity) the same object (OFS does not create a copy and remove the original, it does, in fact move), the reason that this is a problem is that 'obj' (in your first example) is a reference to the acquisition wrapper of the content object, not the content object itself. plone.api.content.move() returns the content object, properly re-wrapped in new acquisition context necessary to reindex.

It is always necessary to have an acquisition-wrapped object (e.g., not aq_base(content)) to re-index, and you always want the correct wrapper referenced (if you do not use the return value from plone.api.content.move(), and were using raw OFS API to move, you would need to get this by traversal from parent folder again at new id/location).


1 Like

Can you file a bug for this against plone.api?

I do not think this is a bug of plone.api. Esp. considering making this in-place vs. returned copy seems to create its own set of unintended consequences. OP had a reference to 'obj' which was pointing at an acquisition wrapper; he tried to re-use that reference after move, which had (understandable) issues. By using the return value of plone.api.content.move(), it appears that OP was able to address the issue.



1 Like

It certainly is a bug in plone.api. Not in code, but in the docs that give no warning at all:

1 Like

Thanks for this, Michael, I have a similar issue. For me this raises the
question of when reindexObject is required after other api.content
methods like rename, transition, etc. Your thoughts?

Hi Mike, its depend on project requirement. For this mentioned project, objects are moved during a workflow transition and reindex is necessary for other usages. For my use case the reindex is not very critical, so I use zeo-worker clock-server to reindex them periodically.
For me I always like to use delayed reindexing so that it does not block or hold back the request. I know collective.indexing can do something like that but it doesn't seem to improve my processes.