Objects can no longer adapt to IPrimaryFieldInfo

I have an issue similar to
TTW Dexterity CT - Could not adapt plone.dexterity.content.Container to interfaces.IPrimaryFieldInfo

The problem arises in a collective.cover carousel tile, when I try to add an item in compose mode. I drag an item into the tile, and it gets ignored. The strange thing is that this site, and this particular use case, has been working for about two years, and I'm not sure what might have changed.

I have traced the problem down to collective.cover.tiles.carousel.CarouselTile.populate_with_object, where this happens:

    try:
        image_size = obj.restrictedTraverse('@@images').getImageSize()
    except:
        image_size = None
    if not image_size:
        return
    super(CarouselTile, self).populate_with_object(obj)

At the end of this, it returns without calling super(..., because image_size is None. The exception thrown is:

(Pdb) obj.restrictedTraverse('@@images').getImageSize()
*** TypeError: ('Could not adapt', <Link at blah>, <InterfaceClass plone.rfc822.interfaces.IPrimaryFieldInfo>)

getImageSize() is in plone.namedfile.scaling.ImageScaling:

def getImageSize(self, fieldname=None):
    if fieldname is not None:
        value = self.guarded_orig_image(fieldname)
        return value.getImageSize()
    value = IPrimaryFieldInfo(self.context).value
    return value.getImageSize()

The error comes from plone.dexterity.primary.PrimaryFieldInfo.__init__, because after it iterates through all the schemata of the context, it can't find any field that provides IPrimaryFieldInfo.

On this site, the Link type has these behaviors:

plone.app.dexterity.behaviors.discussion.IAllowDiscussion
plone.app.dexterity.behaviors.metadata.IDublinCore
plone.app.content.interfaces.INameFromTitle
plone.app.dexterity.behaviors.exclfromnav.IExcludeFromNavigation
plone.app.versioningbehavior.behaviors.IVersionable
plone.app.contenttypes.behaviors.leadimage.ILeadImage
plone.app.dexterity.behaviors.filename.INameFromFileName

I would have thought that ILeadImage would provide the PrimaryField. And since this used to work in the past, I can only assume that the adaptation to IPrimaryFieldInfo used to be successful, and now it's not.
What can I do to make it so that my content returns a proper ImageSize?
(I did hack the code in collective.cover to pass it a fieldName of image, and that works, but with side-effects, e.g. all previous carousel images are deleted.)

These are some of the versions in use:

Plone 4.3.4.1
plone.app.contenttypes 1.1b2
collective.cover 1.0a10
plone.scale 1.3.4
plone.namedfile 2.0.7
plone.dexterity 2.2.4

I think you must try to upgrade collective.cover to a newer version as the code that detects if an object has an image was changed at some point in the past; this is on master branch:

and:

it must be safe to upgrade to latest version, which is 1.2b1, and has tons of bugs fixed and many new features:

don't forget to update the dependencies:

and be careful with some behaviors that are no longer hard dependencies as explained in the README.

it must be safe if you don't have custom tiles as we have taken extra time checking the upgrade steps and all issues were fixed.

if that doesn't work open an issue to check your specific use case (Dexterity-based Link content type with Lead image behavior); it would be nice to have a test added.

I have three custom cover tiles, and the client has no budget for upgrading, so I found a solution here:

So I fixed it by doing this in one of my __init__.py files:

from plone.app.contenttypes.behaviors.leadimage import ILeadImage
from zope.interface import alsoProvides
from plone.rfc822.interfaces import IPrimaryField

alsoProvides(ILeadImage['image'], IPrimaryField)

Not sure if this could be done in zcml. By the way, the link to plone.rfc822 above also explains how a field is marked as primary in schema, using marshal:primary="true". That's how the File and Image schemas do it in their schema in plone.app.contenttypes.

I'd still love to understand why this broke at some point on my client's site, but I may never know.

1 Like