{"record":{"id":"1b8205d4ab45570b","repo":"flowable/flowable-engine","slug":"cannot-combine-onlyinbound-with-onlyoutbound-i","errorCode":null,"errorMessage":"Cannot combine onlyInbound() with onlyOutbound() in the same query","messagePattern":"Cannot combine onlyInbound\\(\\) with onlyOutbound\\(\\) in the same query","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/ChannelDefinitionQueryImpl.java","lineNumber":249,"sourceCode":"\n    protected void checkVersion(Integer version) {\n        if (version == null) {\n            throw new FlowableIllegalArgumentException(\"version is null\");\n        } else if (version <= 0) {\n            throw new FlowableIllegalArgumentException(\"version must be positive\");\n        }\n    }\n\n    @Override\n    public ChannelDefinitionQueryImpl latestVersion() {\n        this.latest = true;\n        return this;\n    }\n    \n    @Override\n    public ChannelDefinitionQuery onlyInbound() {\n        if (onlyOutbound) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyInbound() with onlyOutbound() in the same query\");\n        }\n        this.onlyInbound = true;\n        return this;\n    }\n\n    @Override\n    public ChannelDefinitionQuery onlyOutbound() {\n        if (onlyInbound) {\n            throw new FlowableIllegalArgumentException(\"Cannot combine onlyOutbound() with onlyInbound() in the same query\");\n        }\n        this.onlyOutbound = true;\n        return this;\n    }\n\n    @Override\n    public ChannelDefinitionQuery implementation(String implementation) {\n        if (implementation == null) {\n            throw new FlowableIllegalArgumentException(\"implementation is null\");","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/ChannelDefinitionQueryImpl.java#L231-L267","documentation":"ChannelDefinitionQueryImpl.onlyInbound() throws FlowableIllegalArgumentException if onlyOutbound() was already called on the same query. Inbound and outbound channel type filters are mutually exclusive — a channel definition query can filter for one direction or neither, but combining both would be contradictory, so the builder rejects the second call.","triggerScenarios":"Building a query with chained calls where onlyOutbound() precedes onlyInbound(), e.g. query.onlyOutbound().onlyInbound() or conditionally calling both from branching logic that assumed they could stack.","commonSituations":"Copy-pasting query building code and keeping both directional filters; feature flags that add both filters when misconfigured; misunderstanding the API as additive filtering.","solutions":["Call only one of onlyInbound()/onlyOutbound() per query","If you need both directions, remove both directional filters — the default query returns all channel definitions","Restructure conditional logic so only one branch sets a directional filter","Create two separate queries if you genuinely need inbound and outbound results distinguished"],"exampleFix":"// before\nif (inbound) query.onlyInbound();\nif (outbound) query.onlyOutbound(); // throws when both true\n// after\nif (inbound && !outbound) {\n    query.onlyInbound();\n} else if (outbound && !inbound) {\n    query.onlyOutbound();\n}","handlingStrategy":"validation","validationCode":"if (wantInbound && wantOutbound) {\n    throw new IllegalArgumentException(\"onlyInbound and onlyOutbound are mutually exclusive\");\n}\nChannelDefinitionQuery q = query;\nif (wantInbound) q = q.onlyInbound();\nif (wantOutbound) q = q.onlyOutbound();","typeGuard":"boolean isSingleDirection(boolean inbound, boolean outbound) {\n    return !(inbound && outbound);\n}","tryCatchPattern":"try {\n    query.onlyInbound();\n} catch (FlowableIllegalArgumentException e) {\n    logger.warn(\"Conflicting direction filters: {}\", e.getMessage());\n    query = channelDefinitionQuery(); // rebuild without conflicts\n}","preventionTips":["Treat onlyInbound/onlyOutbound as exclusive: pick at most one per query","Collect direction filters into an enum (INBOUND/OUTBOUND/ALL) instead of booleans","Validate mutually exclusive UI/config options before building the query","If both directions are needed, run two separate queries or drop the filters"],"tags":["flowable","mutually-exclusive","query-builder","invalid-state"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}