apache/incubator-seata · error · IllegalArgumentException

Cannot convert

Error message

Cannot convert {name}

What it means

Thrown by StateMachine.Status.wrap(...) when converting an Apache Seata StateMachine.Status (AC/IN) to the io.seata compatibility enum and the default branch is hit. Both constants are mapped, so the exception can only occur when the two StateMachine$Status enum classes on the classpath were compiled from different Seata versions with mismatched constant sets.

Solutions

  1. Make the compatible artifact (io.seata) and the core artifact (org.apache.seata) the exact same release across all modules.
  2. Verify with 'mvn dependency:tree' / 'gradle dependencies' that only one seata-saga-statelang version resolves.
  3. If you maintain a fork that adds enum constants, regenerate the compatible layer so wrap()/unwrap() cover them.

Example fix

// before (skewed versions)
 // app module: org.apache.seata 2.2.0, common module: io.seata compatible 2.0.0
 StateMachine.Status s = StateMachine.Status.wrap(apacheStatus); // IllegalArgumentException

// after
 dependencyManagement {
     imports { mavenBom("org.apache.seata:seata-parent:2.2.0") }
 }
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> MAPPABLE = Set.of("AC", "IN");

public static StateMachine.Status safeWrap(org.apache.seata.saga.statelang.domain.StateMachine.Status target) {
    if (target != null && !MAPPABLE.contains(target.name())) {
        throw new IllegalStateException("StateMachine.Status '" + target
            + "' unmappable; align io.seata and org.apache.seata versions");
    }
    return StateMachine.Status.wrap(target);
}

Try / catch

try {
    return StateMachine.Status.wrap(target);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("StateMachine.Status unmappable: " + target, e);
}

Prevention

When it happens

Trigger: Calling StateMachine.Status.wrap(target) — typically invoked implicitly when the compatible layer adapts a state machine loaded by the org.apache.seata saga engine — where the runtime org.apache.seata StateMachine.Status enum carries a constant unknown to the compatible jar.

Common situations: Rolling upgrades of a Seata-based saga service where some pods run io.seata 1.x adapters against an org.apache.seata 2.x server; libraries that embed their own copy of seata-saga-statelang; snapshot/local builds compiled against a fork that added a status constant.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/dd559c06ce5eaa47. Report an issue: GitHub.

Appendix: source

Thrown at compatible/src/main/java/io/seata/saga/statelang/domain/StateMachine.java:246

        }

        /**
         * Wrap status.
         *
         * @param target the target
         * @return the status
         */
        public static Status wrap(org.apache.seata.saga.statelang.domain.StateMachine.Status target) {
            if (target == null) {
                return null;
            }
            switch (target) {
                case AC:
                    return AC;
                case IN:
                    return IN;
                default:
                    throw new IllegalArgumentException("Cannot convert " + target.name());
            }
        }

        /**
         * Unwrap org . apache . seata . saga . statelang . domain . state machine . status.
         *
         * @return the org . apache . seata . saga . statelang . domain . state machine . status
         */
        public org.apache.seata.saga.statelang.domain.StateMachine.Status unwrap() {
            switch (this) {
                case AC:
                    return org.apache.seata.saga.statelang.domain.StateMachine.Status.AC;
                case IN:
                    return org.apache.seata.saga.statelang.domain.StateMachine.Status.IN;
                default:
                    throw new IllegalArgumentException("Cannot convert " + this.name());
            }
        }

View on GitHub (pinned to e01f97c6db)