alibaba/spring-ai-alibaba · info · BizException
WORKFLOW_RUN_CANCEL
WORKFLOW_RUN_CANCEL
Error message
Manually terminated
What it means
AbstractExecuteProcessor.preCheck() runs before each workflow node executes. If the workflow context's task status is NodeStatusEnum.STOP, it throws a BizException with code WORKFLOW_RUN_CANCEL to abort the run — the workflow was manually terminated by a user.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/workflow/processor/AbstractExecuteProcessor.java:181
// Node execution error, save execution result and record error information
NodeResult errorNodeResult = NodeResult.error(node, e.getMessage());
errorNodeResult.setInput(JsonUtils.toJson(constructInputParamsMap(node, context)));
handleNodeResult(graph, node, context, errorNodeResult, start);
}
}
/**
* Pre-execution validation checks. Verifies: 1. Workflow is not stopped 2. Node has
* valid successors (unless it's an end node)
* @param graph The workflow graph
* @param node The node to validate
* @param context The workflow context
* @throws BizException if validation fails
*/
public void preCheck(DirectedAcyclicGraph<String, Edge> graph, Node node, WorkflowContext context) {
// boolean b = workflowInnerService.checkValidFlag(context);
if (context.getTaskStatus().equals(NodeStatusEnum.STOP.getCode())) {
throw new BizException(ErrorCode.WORKFLOW_RUN_CANCEL.toError("Manually terminated"));
}
if ((!node.getId().startsWith("End_") && !node.getId().startsWith("IteratorEnd_")
&& !node.getId().startsWith("ParallelEnd_"))
&& CollectionUtils.isEmpty(graph.outgoingEdgesOf(node.getId()))) {
throw new BizException(ErrorCode.WORKFLOW_CONFIG_INVALID
.toError("the current node has no successor node, and it cannot function properly."));
}
}
/**
* Core execution logic to be implemented by concrete processors.
* @param graph The workflow graph
* @param node The node to execute
* @param context The workflow context
* @return NodeResult containing execution results
*/
public abstract NodeResult innerExecute(DirectedAcyclicGraph<String, Edge> graph, Node node,
WorkflowContext context);View on GitHub (pinned to f82da0b50f)
Solutions
- Treat this as expected control flow: catch BizException with code WORKFLOW_RUN_CANCEL and mark the run as cancelled rather than failed
- Ensure the UI only sends cancel when the run is active, and update task status idempotently
- If it fires unexpectedly, check whether some service is writing NodeStatusEnum.STOP into the context erroneously
Example fix
// before
catch (BizException e) { log.error("node failed", e); }
// after
catch (BizException e) {
if (e.getCode() == ErrorCode.WORKFLOW_RUN_CANCEL.getCode()) {
context.setTaskStatus(NodeStatusEnum.STOP.getCode()); return; // expected cancel
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (context.getTaskStatus() == NodeStatusEnum.STOP.getCode()) {
// skip node execution proactively
return;
} Type guard
static boolean isCancelled(WorkflowContext ctx) {
return ctx != null && NodeStatusEnum.STOP.getCode().equals(ctx.getTaskStatus());
} Try / catch
try {
processor.execute(graph, node, context);
} catch (BizException e) {
if (ErrorCode.WORKFLOW_RUN_CANCEL.getCode().equals(e.getCode())) {
log.info("Workflow {} cancelled by user", context.getRequestId());
return;
}
throw e;
} Prevention
- Check task status at loop boundaries before each node
- Handle WORKFLOW_RUN_CANCEL explicitly as control flow, not as failure
- Make cancel-state writes idempotent so status converges quickly
When it happens
Trigger: A user pressed stop/cancel on a running workflow (task status set to STOP in the context), and the next node's execute() calls preCheck() before running.
Common situations: Long-running workflow executions cancelled from the Studio/Admin UI; concurrent cancel requests racing node execution.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/07cf595cbd36f465.
Report an issue: GitHub.