YunaiV/yudao-cloud · error · IllegalArgumentException
未知操作符: {}
Error message
未知操作符: {} What it means
BpmConditionOpCodeEnum.fromCode throws IllegalArgumentException when the condition operator code passed from a BPM simple-model condition node (e.g. Flowable expression builder UI) does not case-insensitively match any defined operator code ('==' , '!=', '>', '>=', '<', '<=', 'contains', '!contain', etc.). The code string comes straight from the JSON saved on the process definition, so a typo or a newer designer's operator will blow up server-side conversion.
Source
Thrown at yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmConditionOpCodeEnum.java:35
GT(">", "大于", " var:getOrDefault(%s, null) > %s "),
GE(">=", "大于等于", " var:getOrDefault(%s, null) >= %s "),
LT("<", "小于", " var:getOrDefault(%s, null) < %s "),
LE("<=", "小于等于", " var:getOrDefault(%s, null) <= %s "),
CONTAINS("contain", "包含", " var:contains(%s, %s) "),
NOT_CONTAINS("!contain", "不包含", " !var:contains(%s, %s) ");
private final String code;
private final String des;
private final String symbol;
public static BpmConditionOpCodeEnum fromCode(String code) {
for (BpmConditionOpCodeEnum op : BpmConditionOpCodeEnum.values()) {
if (op.code.equalsIgnoreCase(code)) {
return op;
}
}
throw new IllegalArgumentException("未知操作符: " + code);
}
}
View on GitHub (pinned to 477be9dd49)
Solutions
- Use one of the codes defined in BpmConditionOpCodeEnum (check the enum constants: ==, !=, >, >=, <, <=, contains, !contain, etc.)
- Align BPM frontend designer and backend module versions so the operator set matches
- Trim/normalize the op string before calling fromCode
Example fix
// before
BpmConditionOpCodeEnum op = BpmConditionOpCodeEnum.fromCode("not-contains"); // throws
// after
String code = StrUtil.trim(rawOp);
BpmConditionOpCodeEnum op = BpmConditionOpCodeEnum.fromCode(code);
// ensure code is one of: "==", "!=", ">", ">=", "<", "<=", "contains", "!contain", ... Defensive patterns
Strategy: validation
Validate before calling
// before fromCode: whitelist the ops your designer emits
Set<String> supported = Arrays.stream(BpmConditionOpCodeEnum.values())
.map(BpmConditionOpCodeEnum::getCode).collect(Collectors.toSet());
if (!supported.contains(rawCode)) {
throw new IllegalArgumentException("op 必须是 " + supported);
} Type guard
boolean isSupportedOp(String code) {
return Arrays.stream(BpmConditionOpCodeEnum.values())
.anyMatch(op -> op.getCode().equalsIgnoreCase(StrUtil.trimToEmpty(code)));
} Prevention
- Derive the designer's operator dropdown from the backend enum contract
- Keep BPM frontend and backend on the same release
- Validate imported process JSON against the enum before deploying
When it happens
Trigger: Saving/converting a simple-model BPMN whose condition node op is misspelled (e.g. 'not-contains', '===', 'CONTAINS ' with trailing space); importing a process definition JSON authored against a different (newer/older) yudao version that added operators this build lacks; hand-edited rule JSON.
Common situations: Frontend designer version newer than backend module (new operators not in the server enum); copy-pasting condition config between projects; whitespace/case drift in stored JSON after export/import.
Related errors
AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14).
Data as JSON: /api/errors/3a38707e78f5dfcc.
Report an issue: GitHub.