RESTAPI-endpoint `@vocabularies/Behaviors` raises a `ValueError`

When requesting the RESTAPI-endpoint @vocabularies for the vocabulary Behaviors we get a ValueError.
Other vocabularies return as expected.

/++api++/@vocabularies shows the vocabulary Behaviors

$ curl -s -X GET "https://classic.demo.plone.org/++api++/@vocabularies" \
    -H "Accept: application/json" \
    --user admin:admin \
    | grep Behavior

# output
    "@id": "https://classic.demo.plone.org/@vocabularies/Behaviors",
    "title": "Behaviors"

But /++api++//@vocabularies/Behaviors raises a ValueError

$ curl -s -X GET "https://classic.demo.plone.org/++api++/@vocabularies/Behaviors" \
    -H "Accept: application/json" \
    --user admin:admin

# output
{
  "context": "https://classic.demo.plone.org",
  "message": "term values must be unique: 'plone.app.dexterity.behaviors.metadata.IBasic'",
  "traceback": [
    "File \"/app/lib/python3.13/site-packages/ZPublisher/WSGIPublisher.py\", line 179, in transaction_pubevents",
    "    yield",
    "",
    "  File \"/app/lib/python3.13/site-packages/ZPublisher/WSGIPublisher.py\", line 388, in publish_module",
    "    response = _publish(request, new_mod_info)",
    "",
    "  File \"/app/lib/python3.13/site-packages/ZPublisher/WSGIPublisher.py\", line 282, in publish",
    "    result = mapply(obj,",
    "                    request.args,",
    "    ...<5 lines>...",
    "                    request,",
    "                    bind=1)",
    "",
    "  File \"/app/lib/python3.13/site-packages/ZPublisher/mapply.py\", line 98, in mapply",
    "    return debug(object, args, context)",
    "",
    "  File \"/app/lib/python3.13/site-packages/ZPublisher/WSGIPublisher.py\", line 68, in call_object",
    "    return obj(*args)",
    "",
    "  File \"/app/lib/python3.13/site-packages/plone/rest/service.py\", line 21, in __call__",
    "    return self.render()",
    "           ~~~~~~~~~~~^^",
    "",
    "  File \"/app/lib/python3.13/site-packages/plone/restapi/services/__init__.py\", line 18, in render",
    "    content = self.reply()",
    "",
    "  File \"/app/lib/python3.13/site-packages/plone/restapi/services/vocabularies/get.py\", line 89, in reply",
    "    vocabulary = factory(self.context)",
    "",
    "  File \"/app/lib/python3.13/site-packages/plone/behavior/vocab.py\", line 12, in BehaviorsVocabularyFactory",
    "    return SimpleVocabulary.fromItems(items)",
    "           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^",
    "",
    "  File \"/app/lib/python3.13/site-packages/zope/schema/vocabulary.py\", line 146, in fromItems",
    "    return cls(terms, *interfaces)",
    "",
    "  File \"/app/lib/python3.13/site-packages/zope/schema/vocabulary.py\", line 118, in __init__",
    "    raise ValueError('term values must be unique: %s' %",
    "                     repr(term.value))"
  ],
  "type": "ValueError"
}

Any hints?

i think this is a bug. for a quick fix, a better filtering is needed in plone.behavior/src/plone/behavior/vocab.py at master · plone/plone.behavior · GitHub

the utility

behaviors = getUtilitiesFor(IBehavior)

return both registrations (via name and via interface) for the same behavior

Example:

plone.app.dexterity.behaviors.metadata.IBasic

and

plone.basic

it ends with a value error in the construction of vocabulary

 ValueError('term values must be unique: %s' %....

because: reg.title, reg.interface.__identifier__ are the same in both behavior items

I think this is related

It looks like this was a long-standing bug in that vocabulary, ever since the ability to give names to behaviors was added. Here is a PR to fix it: Fix ValueError in behavior vocab by davisagli · Pull Request #72 · plone/plone.behavior · GitHub

@mekell Should be fixed in the main branch. Please check.