flowable/flowable-engine · error · FlowableException
Programmatic error: field added to unknown element
Error message
Programmatic error: field added to unknown element '${currentCmmnElement}' What it means
Thrown by ExtensionElementsXMLConverter.readFieldExtension when a <field> extension element is parsed successfully but the current CMMN element's type is not one of the types that accept field extensions. The message says 'programmatic error' because the converter normally guarantees a supported element type; hitting it indicates an internal dispatch gap or an unexpected element on the conversion stack.
Solutions
- Inspect which element type is printed in the message and move the <field> extension to a supported parent (task, listener, decision task).
- Remove the field extension from the unsupported element.
- If it is a legitimate element type, patch/upgrade Flowable so readFieldExtension handles that type (likely a converter bug).
Example fix
<!-- before: field on unsupported element -->
<caseTask id="ct1">
<extensionElements>
<flowable:field name="x" stringValue="y"/>
</extensionElements>
</caseTask>
<!-- after: move field to the listener that needs it -->
<caseTask id="ct1">
<extensionElements>
<flowable:taskListener event="end" class="com.acme.Listener">
<flowable:field name="x" stringValue="y"/>
</flowable:taskListener>
</extensionElements>
</caseTask> Defensive patterns
Strategy: validation
Validate before calling
// Only emit <field> extensions inside elements known to accept them
Set<String> fieldHosts = Set.of("humanTask", "serviceTask", "decisionTask", "caseTask", "processTask", "taskListener", ...
// assert extension parent type ∈ fieldHosts before conversion Type guard
boolean supportsFieldExtension(BaseElement el) {
return el instanceof CmmnActivity || el instanceof FlowableListener;
} Try / catch
try {
cmmnModel = converter.convertToCmmnModel(stream, encoding);
} catch (FlowableException e) {
if (e.getMessage().startsWith("Programmatic error: field added to unknown element")) {
// relocate or remove the field extension on the printed element
}
throw e;
} Prevention
- Place field extensions only on tasks and listeners, never on structural elements (stages, criteria, sentries).
- Treat this as a converter bug signal if your XML looks correct — check for patched element types not covered in readFieldExtension.
- Keep Flowable upgraded so newly supported element types have handler branches.
When it happens
Trigger: A <flowable:field> extension placed inside <extensionElements> of a CMMN element type that has no handler branch in readFieldExtension (not a task/listener/decision task etc.). Usually signals a converter bug or an element type added to the stack unexpectedly.
Common situations: Custom/patched Flowable versions where a new element type was not added to readFieldExtension; users copying <field> extensions onto unsupported CMMN elements via hand-edited XML.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- A dynamically created plan item can only be injected into a…
- A dynamically created plan item can only be injected into a…
- A 'maxInstanceCount' on a repetition rule with value '0' is…
- a suspended
- activatedBefore is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2b3f73c00cd7e96e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/ExtensionElementsXMLConverter.java:284
readyWithFieldExtension = true;
}
}
} catch (Exception e) {
LOGGER.warn("Error parsing field extension child elements", e);
}
}
CmmnElement currentCmmnElement = conversionHelper.getCurrentCmmnElement();
if (currentCmmnElement instanceof ServiceTask) {
((ServiceTask) currentCmmnElement).getFieldExtensions().add(extension);
} else if (currentCmmnElement instanceof DecisionTask) {
((DecisionTask) currentCmmnElement).getFieldExtensions().add(extension);
} else if (currentCmmnElement instanceof FlowableListener) {
((FlowableListener) currentCmmnElement).getFieldExtensions().add(extension);
} else {
throw new FlowableException("Programmatic error: field added to unknown element '" + currentCmmnElement + "'");
}
}
protected void readHttpRequestHandler(XMLStreamReader xtr, ConversionHelper conversionHelper) {
BaseElement cmmnElement = conversionHelper.getCurrentCmmnElement();
if (!(cmmnElement instanceof HttpServiceTask)) {
return;
}
FlowableHttpRequestHandler requestHandler = new FlowableHttpRequestHandler();
setImplementation(xtr, requestHandler);
((HttpServiceTask) cmmnElement).setHttpRequestHandler(requestHandler);
}
protected void readHttpResponseHandler(XMLStreamReader xtr, ConversionHelper conversionHelper) {
BaseElement cmmnElement = conversionHelper.getCurrentCmmnElement();View on GitHub (pinned to d6d39ce1c6)