flowable/flowable-engine · error · ActivitiIllegalArgumentException
invalid: multiple sources
Error message
invalid: multiple sources ${this.streamSource} and ${streamSource} What it means
A single BpmnParse instance can only have one input source. setStreamSource throws ActivitiIllegalArgumentException if a source (stream, string, resource, or URL) was already set on this parser instance, to prevent ambiguous input.
Solutions
- Create a fresh BpmnParse instance (via processEngineConfiguration.getBpmnParser().createParse()) for each source you parse
- Remove the duplicate source-setting call so exactly one source is configured per parse
- If parsing many resources, loop and build a new parse per iteration instead of reusing the object
Example fix
// before (reuse) BpmnParse parse = parser.createParse().sourceResource(a); parse.sourceString(xml); // throws // after BpmnParse parse = parser.createParse().sourceResource(a); BpmnParse parse2 = parser.createParse().sourceString(xml);
Defensive patterns
Strategy: type-guard
Validate before calling
// guard before reuse
if (parse != null && alreadyConfigured) {
parse = processEngineConfiguration.getBpmnParser().createParse();
} Type guard
static boolean canSetSource(BpmnParse parse) {
return parse != null; // treat one parse per source: never set two sources
} Try / catch
try {
parse.sourceString(xml);
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().startsWith("invalid: multiple sources")) {
parse = parser.createParse().sourceString(xml); // fresh parse
}
} Prevention
- Create a new BpmnParse per document; never reuse parse objects
- Do not chain multiple source*() calls on the same instance
- In loops, instantiate the parser/parse inside the loop body
When it happens
Trigger: Calling setStreamSource (directly or via sourceString/sourceInputStream/sourceResource/sourceUrl) twice on the same BpmnParse object.
Common situations: Reusing a BpmnParse/parse helper object across multiple deployments in a loop; chaining two source-setting calls by mistake; copy-pasted parse setup code that sets both a resource and a string.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- malformed url
- Activity needed for multi instance cannot bv found
- end event with cancelEventDefinition only supported inside…
- Error parsing XML
- Error parsing XML
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/44dcab765ae5d370.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/parser/BpmnParse.java:274
public BpmnParse sourceResource(String resource, ClassLoader classLoader) {
if (name == null) {
name(resource);
}
setStreamSource(new ResourceStreamSource(resource, classLoader));
return this;
}
public BpmnParse sourceString(String string) {
if (name == null) {
name("string");
}
setStreamSource(new StringStreamSource(string));
return this;
}
protected void setStreamSource(StreamSource streamSource) {
if (this.streamSource != null) {
throw new ActivitiIllegalArgumentException("invalid: multiple sources " + this.streamSource + " and " + streamSource);
}
this.streamSource = streamSource;
}
/**
* Parses the 'definitions' root element
*/
protected void transformProcessDefinitions() {
sequenceFlows = new HashMap<>();
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable()) {
bpmnParserHandlers.parseElement(this, process);
}
}
if (!processDefinitions.isEmpty()) {
processDI();
}View on GitHub (pinned to d6d39ce1c6)