apache/incubator-seata · error · FrameworkException

TCC bean name cannot be null or empty

Error message

TCC bean name cannot be null or empty

What it means

Thrown by the compatible TCC interceptor parser when a @TwoPhaseBusinessAction annotation has a blank name attribute. The name becomes the TCCResource actionName (the resource identity registered with the TC), so an empty name would make the branch unresolvable and is rejected at parser time.

Source

Thrown at compatible/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java:68

        // register resource and enhance with interceptor
        registerResource(target, methodClassMap);

        return new TccActionInterceptorHandler(
                target, methodsToProxy.stream().map(Method::getName).collect(Collectors.toSet()));
    }

    @Override
    protected Class<? extends Annotation> getAnnotationClass() {
        return TwoPhaseBusinessAction.class;
    }

    protected Resource createResource(Object target, Class<?> targetServiceClass, Method m, Annotation annotation)
            throws NoSuchMethodException {
        TwoPhaseBusinessAction twoPhaseBusinessAction = (TwoPhaseBusinessAction) annotation;
        TCCResource tccResource = new TCCResource();
        if (StringUtils.isBlank(twoPhaseBusinessAction.name())) {
            throw new FrameworkException("TCC bean name cannot be null or empty");
        }
        tccResource.setActionName(twoPhaseBusinessAction.name());
        tccResource.setTargetBean(target);
        tccResource.setPrepareMethod(m);
        tccResource.setCommitMethodName(twoPhaseBusinessAction.commitMethod());
        tccResource.setCommitMethod(targetServiceClass.getMethod(
                twoPhaseBusinessAction.commitMethod(), twoPhaseBusinessAction.commitArgsClasses()));
        tccResource.setRollbackMethodName(twoPhaseBusinessAction.rollbackMethod());
        tccResource.setRollbackMethod(targetServiceClass.getMethod(
                twoPhaseBusinessAction.rollbackMethod(), twoPhaseBusinessAction.rollbackArgsClasses()));
        // set argsClasses
        tccResource.setCommitArgsClasses(twoPhaseBusinessAction.commitArgsClasses());
        tccResource.setRollbackArgsClasses(twoPhaseBusinessAction.rollbackArgsClasses());
        // set phase two method's keys
        tccResource.setPhaseTwoCommitKeys(
                this.getTwoPhaseArgs(tccResource.getCommitMethod(), twoPhaseBusinessAction.commitArgsClasses()));
        tccResource.setPhaseTwoRollbackKeys(
                this.getTwoPhaseArgs(tccResource.getRollbackMethod(), twoPhaseBusinessAction.rollbackArgsClasses()));

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Set a unique non-empty name on every @TwoPhaseBusinessAction, e.g. name = "createOrderTccAction".
  2. Keep names stable across releases — they identify the branch resource on the TC.
  3. Add a build-time or test-time check that all TwoPhaseBusinessAction annotations have names.

Example fix

// before
@TwoPhaseBusinessAction(commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext ctx, Long id) { ... }

// after
@TwoPhaseBusinessAction(name = "createOrderTccAction", commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext ctx, Long id) { ... }
Defensive patterns

Strategy: validation

Validate before calling

TwoPhaseBusinessAction a = method.getAnnotation(TwoPhaseBusinessAction.class);
if (a == null || a.name() == null || a.name().trim().isEmpty()) {
    throw new IllegalStateException("@TwoPhaseBusinessAction on " + method + " needs a non-empty name");
}

Try / catch

try {
    // parser scans bean at startup
} catch (FrameworkException e) {
    if (e.getMessage() != null && e.getMessage().contains("TCC bean name")) {
        throw new ConfigurationException("a @TwoPhaseBusinessAction is missing its name attribute", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Declaring @TwoPhaseBusinessAction(commitMethod=..., rollbackMethod=...) without setting name, or setting name = "" / whitespace. Detected when the parser scans the bean and builds the TCCResource.

Common situations: Copy-pasted TCC annotations with the name attribute accidentally deleted; refactoring that moved the annotation but dropped its attributes; assuming name defaults to the method name (it does not).

Related errors


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