AttributeError: 'NO_VALUE' object has no attribute 'getPhysicalPath'

We have this RelationChoice field (Python 3, Plone 5.2.1)

    directives.widget(
        'reference',
        RelatedItemsFieldWidget,
        pattern_options={
            'selectableTypes': ['Document', 'Link', 'File'],
            'basePath': '/',
            'favorites': [],
        },
    )
    reference = RelationChoice(
        title=_(u'Reference'),
        vocabulary='plone.app.vocabularies.Catalog',
        required=False,
    )

which leads to

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 156, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 338, in publish_module
  Module ZPublisher.WSGIPublisher, line 256, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 62, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.add, line 143, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 132, in update
  Module z3c.form.form, line 136, in updateWidgets
  Module plone.app.drafts.dexterity, line 95, in update
  Module z3c.form.field, line 277, in update
  Module z3c.form.browser.multi, line 63, in update
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.widget, line 496, in update
  Module Products.CMFPlone.patches.z3c_form, line 47, in _wrapped
  Module z3c.form.widget, line 132, in update
  Module z3c.form.widget, line 491, in value
  Module collective.z3cform.datagridfield.datagridfield, line 177, in updateWidgets
  Module collective.z3cform.datagridfield.datagridfield, line 149, in getWidget
  Module z3c.form.browser.widget, line 171, in update
  Module z3c.form.object, line 217, in update
  Module collective.z3cform.datagridfield.datagridfield, line 311, in updateWidgets
  Module z3c.form.object, line 208, in updateWidgets
  Module collective.z3cform.datagridfield.datagridfield, line 439, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 132, in update
  Module collective.z3cform.datagridfield.datagridfield, line 446, in updateWidgets
  Module z3c.form.form, line 136, in updateWidgets
  Module z3c.form.field, line 277, in update
  Module plone.app.z3cform.widget, line 527, in update
  Module z3c.form.browser.text, line 36, in update
  Module z3c.form.browser.widget, line 171, in update
  Module Products.CMFPlone.patches.z3c_form, line 47, in _wrapped
  Module z3c.form.widget, line 112, in update
  Module zope.schema._field, line 507, in bind
  Module zope.schema._field, line 491, in _resolve_vocabulary
  Module Zope2.App.schema, line 32, in get
  Module plone.app.vocabularies.catalog, line 647, in __call__
AttributeError: 'NO_VALUE' object has no attribute 'getPhysicalPath'

What is missing here?

I had to do some handstands in Plone 5.2 to get a RelatedItems widget to display properly. Maybe this is some use?

from .utils import default_pattern_options
from .utils import default_base_path

@provider(IFormFieldProvider)
class IRelatedTeaserImageBehavior(model.Schema):

    related_image = RelationChoice(
        title=u"Related Teaser Image",
        description=u"Add a teaser image",
        required=False,
        default=None,
        vocabulary='plone.app.vocabularies.Catalog'
        )
    directives.widget(
        'related_image',
        RelatedItemsFieldWidget,
        pattern_options = {
            'recentlyUsed': True,
            'basePath'    : default_base_path,
            'mode'        : 'auto',
            'favorites'   : default_pattern_options,
            'folderTypes': ['Folder', 'LIF', 'LRF'],
            'selectableTypes' : ['Image'],
        }
    )

in utils.py

def default_pattern_options(context=None):
    """ default pattern for RelatedItems widget
    """
    portal = api.portal.get()

    # can this actually happen?
    if not context:
        request = getRequest()
        context = request.PARENTS[0]

    language = ILanguage(context).get_language()

    # this should return the portal if plone.app.multilingual is not installed
    language_root = portal.get(language, portal)

    favorite_items = [{
        'title': language_root.title_or_id(),
        'path': '/'.join(language_root.getPhysicalPath()),
    }]

    more_items = api.content.find(
          context=language_root,
          portal_type = ['Folder', 'LIF'],
          depth = 1,
          sort_on = 'sortable_title',
    )

    for item in more_items:
        # restrict to assets folders
        if 'assets' in item.getId:
            favorite_items.append({
                'title': item.Title,
                'path' : item.getPath(),
            })

    return favorite_items


def default_base_path(context=None):
    """ default base path for RelatedItems widget
    """
    portal = api.portal.get()

    # can this actually happen?
    if not context:
        request = getRequest()
        context = request.PARENTS[0]

    language = ILanguage(context).get_language()

    # this should return the portal if plone.app.multilingual is not installed
    language_root = portal.get(language, portal)

    root_path = '/'.join(language_root.getPhysicalPath())

    return root_path

"Works for me" - I can't remember where I borrowed this from...

Plone Foundation Code of Conduct