apache/incubator-seata · error · IllegalArgumentException
non-BusinessActionContext parameter should use annotation Bu
Error message
non-BusinessActionContext parameter should use annotation BusinessActionContextParameter
What it means
Thrown by the compatible TCC parser while validating a TCC method signature: every parameter that is not a BusinessActionContext must be annotated with @BusinessActionContextParameter. This is how the parser knows which parameters to propagate into the rollback/commit context; unannotated business parameters make branch retry impossible to bind correctly.
Source
Thrown at compatible/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java:110
String[] keys = new String[parameterAnnotations.length];
/*
* get parameter's key
* if method's parameter list is like
* (BusinessActionContext, @BusinessActionContextParameter("a") A a, @BusinessActionContextParameter("b") B b)
* the keys will be [null, a, b]
*/
for (int i = 0; i < parameterAnnotations.length; i++) {
for (int j = 0; j < parameterAnnotations[i].length; j++) {
if (parameterAnnotations[i][j] instanceof BusinessActionContextParameter) {
BusinessActionContextParameter param = (BusinessActionContextParameter) parameterAnnotations[i][j];
String key =
io.seata.integration.tx.api.interceptor.ActionContextUtil.getParamNameFromAnnotation(param);
keys[i] = key;
break;
}
}
if (keys[i] == null && !(argsClasses[i].equals(BusinessActionContext.class))) {
throw new IllegalArgumentException("non-BusinessActionContext parameter should use annotation "
+ "BusinessActionContextParameter");
}
}
return keys;
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- Annotate every non-BusinessActionContext parameter with @BusinessActionContextParameter("paramName").
- Ensure the lone BusinessActionContext parameter (if any) is exactly of type BusinessActionContext — the parser exempts only that type.
- Remove extraneous unpropagated parameters from the TCC method signature.
Example fix
// before
@TwoPhaseBusinessAction(name = "orderTcc", commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext ctx, Long orderId, String note) { ... }
// after
@TwoPhaseBusinessAction(name = "orderTcc", commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext ctx,
@BusinessActionContextParameter("orderId") Long orderId,
@BusinessActionContextParameter("note") String note) { ... } Defensive patterns
Strategy: validation
Validate before calling
for (java.lang.reflect.Parameter p : method.getParameters()) {
boolean isCtx = p.getType().equals(BusinessActionContext.class);
boolean annotated = p.isAnnotationPresent(BusinessActionContextParameter.class);
if (!isCtx && !annotated) {
throw new IllegalStateException("parameter '" + p.getName()
+ "' of " + method + " needs @BusinessActionContextParameter");
}
} Try / catch
try {
// bean scan / interceptor parse at startup
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("BusinessActionContextParameter")) {
throw new ConfigurationException("TCC method signature invalid: annotate non-context parameters", e);
}
throw e;
} Prevention
- Annotate every business parameter of TCC methods with @BusinessActionContextParameter("name").
- Only the BusinessActionContext-typed parameter may go unannotated.
- Cover TCC interfaces with a signature-validation test so regressions fail at build time.
When it happens
Trigger: A @TwoPhaseBusinessAction prepare/commit/rollback method has a parameter that is neither BusinessActionContext nor annotated @BusinessActionContextParameter. The parser walks parameterAnnotations and argsClasses and throws on the first such parameter.
Common situations: Adding a new parameter to a TCC method and forgetting the annotation; migrating plain interfaces to TCC; thinking the annotation is optional; version upgrades re-enabling strict parsing that was previously lenient.
Related errors
- @BusinessActionContextParameter 's params can not null
- TCC bean name cannot be null or empty
- Couldn't parser any Remoting info
- Two or more start states, ${target} and ${definitions.StartS
- URL must not be null or blank
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/8a3bf2cfa3a8383c.
Report an issue: GitHub.