flowable/flowable-engine · error · FlowableException

invalid: multiple sources

Error message

invalid: multiple sources ${existingStreamSource} and ${newStreamSource}

What it means

DmnParse (DmnParse in modules/flowable-dmn-engine/.../parser/DmnParse.java:173) can only hold one stream source. setStreamSource is the single choke point used by sourceInputStream, sourceUrl, sourceResource and sourceString; if a second source is set after a first one, the builder throws FlowableException('invalid: multiple sources ...'). This guards against ambiguous input where the DMN XML would be read from more than one place.

Solutions

  1. Create a new DmnParse instance for each DMN resource instead of reusing one.
  2. Call exactly one source* method per parse; remove the redundant sourceInputStream/sourceUrl/sourceResource/sourceString call.
  3. If you must replace the source, reset the parser (new instance) since streamSource has no setter-clear API.

Example fix

// before
DmnParse parse = new DmnParse(engineConfiguration);
parse.sourceResource("a.dmn");
parse.sourceResource("b.dmn"); // throws invalid: multiple sources
// after
DmnParse parseA = new DmnParse(engineConfiguration);
parseA.sourceResource("a.dmn");
DmnParse parseB = new DmnParse(engineConfiguration);
parseB.sourceResource("b.dmn");
Defensive patterns

Strategy: validation

Validate before calling

if (parserHasSource(parse)) { throw new IllegalStateException("DmnParse already has a source; create a new instance"); }
boolean parserHasSource(DmnParse p) { return p != null && p.getStreamSource() != null; }

Type guard

boolean canSetSource(DmnParse p) { return p.getStreamSource() == null; }

Prevention

When it happens

Trigger: Calling two of sourceInputStream/sourceUrl/sourceResource/sourceString on the same DmnParse instance, or calling any of them on an instance that already had a source set (e.g. reused parser/builder object).

Common situations: Reusing a shared parser or fluent builder for multiple DMN resources in a loop; copying example code that chains both sourceResource(...) and sourceInputStream(...); wiring a custom deployer that sets a default source and then the user's source.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/6f9960e3b36b4ba2. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/parser/DmnParse.java:173

    public DmnParse sourceResource(String resource) {
        if (name == null) {
            name(resource);
        }
        setStreamSource(new ResourceStreamSource(resource));
        return this;
    }

    public DmnParse 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 FlowableException("invalid: multiple sources " + this.streamSource + " and " + streamSource);
        }
        this.streamSource = streamSource;
    }

    public String getSourceSystemId() {
        return sourceSystemId;
    }

    public DmnParse setSourceSystemId(String sourceSystemId) {
        this.sourceSystemId = sourceSystemId;
        return this;
    }

    /*
     * ------------------- GETTERS AND SETTERS -------------------
     */

    public boolean isValidateSchema() {

View on GitHub (pinned to d6d39ce1c6)