Describing custom elements (non bpmn namespace) via the properties panel


First off, i tip my hat to the community support, engagement, and lots of usable and clear to follow examples. This makes it very easy to get very far by just having a look at the available material.

Thus far i have found two examples, one which details how to extend the properties panel with a provider and custom “parts” or input fields, and another detailing how to add a custom meta-model.

I am trying to add fields to the properties panel that would make it possible to create and update custom elements. (elements that do not pertain to the bpmn namespace).

To make it easier to troubleshoot i have employed an already available descriptor: bpmn-js-example-model-extension/qa.json at master · bpmn-io/bpmn-js-example-model-extension · GitHub

Here we have an example of a valid bpmn document containing the extensions described in the descriptor: bpmn-js-example-model-extension/diagram.bpmn at master · bpmn-io/bpmn-js-example-model-extension · GitHub

I have also borrowed parts from the bpmn-js-properties-panel module:bpmn-js-properties-panel/DocumentationProps.js at master · bpmn-io/bpmn-js-properties-panel · GitHub

The latter have been altered to fit the descriptor, and also trimmed, but the mechanism and logic remains the same.

Here are the specifics of this part

 import entryFactory from "bpmn-js-properties-panel/lib/factory/EntryFactory";
import cmdHelper from "bpmn-js-properties-panel/lib/helper/CmdHelper"
import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';

export default function (group, element, bpmnFactory, translate) {


    var getValue = function (businessObject) {
        return function (element) {
            // what exactly does the businessObject getter do
            // what is a *businessObject*
            var documentations = businessObject && businessObject.get('comment'),
                text = (documentations && documentations.length > 0) ? documentations[0].text : '';

            return { comment: text };

    var setValue = function (businessObject) {
        return function (element, values) {
            var newObjectList = [];
            // breaks here --> Error: unknown type <qa:comment>
            // does not manage to create the qa:comment element
            if (typeof values.comment !== 'undefined' && values.comment !== '') {
                newObjectList.push(bpmnFactory.create('qa:comment', {
                    text: values.comment


            return cmdHelper.setList(element, businessObject, 'comment', newObjectList);

    // Element Documentation
    var elementDocuEntry = entryFactory.textBox(translate, {
        id: 'scenario',
        label: translate('scenario documentation'),
        modelProperty: 'comment'

    elementDocuEntry.set = setValue(getBusinessObject(element));

    elementDocuEntry.get = getValue(getBusinessObject(element));



My issue being:
The bpmnFactory.create function throws an error because if fails to create the qa:comment element, even though it is described in the descriptor.

Why is this so, and what exactly is the businessObject (not a very intuitive name?)

Hope you could help steer me in the right direction.



Edit: make the title a bit more descriptive

Hi @hpl002 , welcome to the forum and thanks for your detailed description!

what exactly is the businessObject

That’s our internal representation of the related BPMN 2.0 XML for each element.

Can you maybe share your code inside a CodeSandbox? It will be even easier for us to reproduce your problem and provide you a solution.

Absolutely. Will get back to you later today.

But creating custom elements (non bpmn namespace elements) via


is allowed?

Here is the sandbox that successfully replicates this same erorr:

Error is triggered by simply typing anything in property panel input form

Thanks for sharing. Some notes on your implementation.

Make sure you’re registering for the correct moddle extension

const modeler = new Modeler({
  /* ... */
  moddleExtensions: {
    qa: descriptor
  /* ... */

Also, following the example, make sure your extension goes into extensionElements.

I’d also avoid using the bpmnFactory and using moddle directly, since the bpmnFactory has some BPMN 2.0 behaviors included.

const moddle = modeler.get("moddle");

const comment = moddle.create("qa:Comment", {
  text: values.comment

Appreciate the quick reply!

Will have a look at this later today and add resolving comments if this sorts my issues.

Thanks again


Manged to resolve my issues.

Future readers(novices):
Have a look at the sandbox for a working implementation, but there are also some concepts and mechanisms that you should be aware of.

  • All custom elements have to be wrapped in the :extensionElements. The properties panel ships with some helper modules that you can borrow. These make this a lot easier. See scenario.js in the sandbox for specifics.
        <qa:comment>yello there friendo</qa:comment>
  • All events in the modeler er propagated through the providers. This is how you hook onto changes. There is no direct link, you simply have to hook onto whatever model change you need.
    This makes is very flexible, but maybe a bit tricky to get working on the first go.

  • Descriptors are easy to work with, see this for details.

1 Like