apache/incubator-seata · error · IllegalArgumentException
branchType must be not null
Error message
branchType must be not null
What it means
RootContext.bindBranchType is annotated @Nonnull and throws IllegalArgumentException on a null argument. It stores the current branch type into the thread-bound context (CONTEXT_HOLDER); a null would corrupt later getBranchType/unbind logic, so it fails fast.
Source
Thrown at core/src/main/java/org/apache/seata/core/context/RootContext.java:241
if (inGlobalTransaction()) {
BranchType branchType = (BranchType) CONTEXT_HOLDER.get(KEY_BRANCH_TYPE);
if (branchType != null) {
return branchType;
}
// Returns the default branch type.
return DEFAULT_BRANCH_TYPE != null ? DEFAULT_BRANCH_TYPE : BranchType.AT;
}
return null;
}
/**
* bind branch type
*
* @param branchType the branch type
*/
public static void bindBranchType(@Nonnull BranchType branchType) {
if (branchType == null) {
throw new IllegalArgumentException("branchType must be not null");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("bind branch type {}", branchType);
}
CONTEXT_HOLDER.put(KEY_BRANCH_TYPE, branchType);
}
/**
* unbind branch type
*
* @return the previous branch type or null
*/
@Nullable
public static BranchType unbindBranchType() {
BranchType unbindBranchType = (BranchType) CONTEXT_HOLDER.remove(KEY_BRANCH_TYPE);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("unbind branch type {}", unbindBranchType);View on GitHub (pinned to e01f97c6db)
Solutions
- Guard the call site: only bind when the extracted value is non-null.
- Fix the upstream extraction — if the annotation attribute is optional, choose BranchType.AT explicitly or skip binding.
- Update third-party starters/adapters to a version compatible with the @Nonnull contract.
Example fix
// before
RootContext.bindBranchType(branchType);
// after
if (branchType != null) {
RootContext.bindBranchType(branchType);
} Defensive patterns
Strategy: validation
Validate before calling
if (branchType != null) {
RootContext.bindBranchType(branchType);
} else {
LOG.debug("no branch type to bind, skipping");
} Type guard
boolean bindable(BranchType t) { return t != null; } Try / catch
catch (IllegalArgumentException e) {
if (e.getMessage().contains("not null")) { /* skip binding, keep context intact */ }
else throw e;
} Prevention
- Null-check extracted annotation attributes before binding
- Always pair bind with unbind in finally to keep thread context clean
When it happens
Trigger: Programmatic call bindBranchType(null) — typically an interceptor or framework adapter that extracts a branch type from an annotation/request and passes it through without a null check (e.g. custom SAGA/TCC integration code where the attribute was absent).
Common situations: Custom Seata integration glue, a mirated SDK version where a previously-nullable signature now throws, or interceptors running on endpoints that do not carry the branch-type attribute.
Related errors
- Unknown BranchType[{ordinal}]
- Unknown BranchType[{name}]
- @BusinessActionContextParameter 's params can not null
- bytes is null
- bytes is null
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/4bb2cc7dbe70883b.
Report an issue: GitHub.