alibaba/COLA · error · RuntimeException

execute not supported for OR relation composite

Error message

execute not supported for OR relation composite

What it means

AnyRules is an OR-composite rule in the COLA rule engine: it evaluates children with short-circuit OR semantics but does not support executing actions. Calling execute() directly on an AnyRules composite is intentionally unsupported, so it unconditionally throws this RuntimeException. Composition rules should only be used to drive evaluation of their children, not to execute facts themselves.

Source

Thrown at cola-components/cola-component-ruleengine/src/main/java/com/alibaba/cola/ruleengine/core/AnyRules.java:26

public class AnyRules extends CompositeRule{

    public static CompositeRule anyOf(Rule... rules) {
        CompositeRule instance = new AnyRules();
        Collections.addAll(instance.rules, rules);
        return instance;
    }

    @Override
    public boolean evaluate(Facts facts) {
        if (rules.stream().anyMatch(rule -> rule.evaluate(facts)))
            return true;
        return false;
    }

    @Override
    public void execute(Facts facts) {
        //不支持OR relation
        throw new RuntimeException("execute not supported for OR relation composite");
    }

    @Override
    protected boolean doApply(Facts facts) {
        for (Rule rule : rules) {
            //短路操作,只要第一个rule成功执行,其它就不执行了
            if (rule.apply(facts)) {
                return true;
            }
        }
        return false;
    }
}

View on GitHub (pinned to 352e1a8675)

Solutions

  1. Do not call execute() on AnyRules composites; execute only leaf rules (e.g. SimpleRules/LightRules) or iterate rules returned by the composite
  2. Use evaluate(facts) on the AnyRules composite to get OR short-circuit evaluation of children, then execute child rules that return true
  3. Restructure the rule tree so composites only contain conditional logic and actions live in leaf rules

Example fix

// before
AnyRules<Integer, MyContext> orRule = AnyRules.or(ruleA, ruleB);
orRule.execute(facts); // throws

// after
if (orRule.evaluate(facts)) {
    matchedRule.execute(facts);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rule instanceof AnyRules) {
    boolean matched = rule.evaluate(facts);
    // execute only leaf rules that matched
}

Type guard

boolean isExecutableRule(Object rule) {
    return rule != null && !(rule instanceof AnyRules);
}

Try / catch

try {
    composite.execute(facts);
} catch (RuntimeException e) {
    if (e.getMessage().contains("execute not supported for OR relation")) {
        // fall back to evaluate + child execution
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling rule.execute(facts) on a rule built via AnyRules.or(...) instead of calling execute on a leaf/child rule, or calling execute on a composite parent rather than letting doApply/evaluate drive child execution.

Common situations: Developers build an OR composite rule and then treat it like a normal rule, invoking execute() in a rules engine runner loop; confusion over the Rule interface's execute contract applying to composites.

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


AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08). Data as JSON: /api/errors/66ccb3528673d249. Report an issue: GitHub.