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
- Set a unique non-empty name on every @TwoPhaseBusinessAction, e.g. name = "createOrderTccAction".
- Keep names stable across releases — they identify the branch resource on the TC.
- 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
- Set name on every @TwoPhaseBusinessAction; treat it as mandatory, not optional.
- Add an ArchUnit/reflection test asserting all TwoPhaseBusinessAction annotations have non-blank names.
- Keep names stable — they key the branch resource on the TC.
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
- non-BusinessActionContext parameter should use annotation Bu
- could not convert '{size}' to byte length
- {dataName} data is too large, size={length}
- Unknown BranchType[{name}]
- @BusinessActionContextParameter 's params can not null
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/52b3646f9d88ff56.
Report an issue: GitHub.