conductor-oss/conductor · error · TerminateWorkflowException
Error while evaluating script: %s
Error message
Error while evaluating script: %s
What it means
Thrown by DecisionTaskMapper.getEvaluatedCaseValue() when ScriptEvaluator.eval() throws an exception while evaluating a decision task's caseExpression. The caseExpression is a GraalJS JavaScript expression that determines which branch of a DECISION task to follow. Any script error — syntax error, undefined variable, type coercion failure — causes the workflow to be terminated via TerminateWorkflowException. The original exception is logged separately (LOGGER.error with the exception), but the TerminateWorkflowException only carries the expression string, not the root cause message.
Source
Thrown at core/src/main/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapper.java:143
* @param workflowTask: The decision task that has the case expression to be evaluated.
* @param taskInput: the input which has the values that will be used in evaluating the case
* expression.
* @return A String representation of the evaluated result
*/
@VisibleForTesting
String getEvaluatedCaseValue(WorkflowTask workflowTask, Map<String, Object> taskInput) {
String expression = workflowTask.getCaseExpression();
String caseValue;
if (StringUtils.isNotBlank(expression)) {
LOGGER.debug("Case being evaluated using decision expression: {}", expression);
try {
// Evaluate the expression by using the GraalJS based script evaluator
Object returnValue = ScriptEvaluator.eval(expression, taskInput);
caseValue = (returnValue == null) ? "null" : returnValue.toString();
} catch (Exception e) {
String errorMsg = String.format("Error while evaluating script: %s", expression);
LOGGER.error(errorMsg, e);
throw new TerminateWorkflowException(errorMsg);
}
} else { // In case of no case expression, get the caseValueParam and treat it as a string
// representation of caseValue
LOGGER.debug(
"No Expression available on the decision task, case value being assigned as param name");
String paramName = workflowTask.getCaseValueParam();
caseValue = "" + taskInput.get(paramName);
}
return caseValue;
}
}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Check the server log for the original exception (LOGGER.error logs it with stack trace) — it will show the exact JavaScript error.
- Fix the caseExpression to handle null/undefined values: use defensive checks like '$.input?.status || "default"'.
- Test the expression in a GraalJS REPL with a sample of the actual task input data.
- If the field may be absent, prefer caseValueParam over caseExpression for simple key lookups.
Example fix
// before
{
"type": "DECISION",
"caseExpression": "$.input.status.toLowerCase()"
}
// after
{
"type": "DECISION",
"caseExpression": "$.input.status ? $.input.status.toLowerCase() : 'unknown'"
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the case expression before workflow registration
try {
ScriptEvaluator.eval(caseExpression, sampleInput);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid caseExpression: " + e.getMessage());
} Try / catch
// The TerminateWorkflowException terminates the workflow.
// Prevention is in the definition: test expressions with real data.
// In a custom DeciderService wrapper:
try {
String caseValue = getEvaluatedCaseValue(workflowTask, taskInput);
} catch (TerminateWorkflowException e) {
LOGGER.error("Decision expression failed for task {}: {}",
workflowTask.getTaskReferenceName(), e.getMessage());
// cannot recover — workflow will be terminated
} Prevention
- Test caseExpressions with representative input data before deploying.
- Use null-safe operators (?.) in GraalJS expressions.
- Prefer caseValueParam for simple key lookups to avoid script evaluation entirely.
- Monitor server logs for the original ScriptEvaluator exception during expression failures.
When it happens
Trigger: A DECISION task with a caseExpression referencing a variable that is null or undefined at runtime. A JavaScript syntax error in the caseExpression. A type error in the expression (e.g., calling .length on a number). The expression uses a GraalJS feature that is not permitted by the sandbox.
Common situations: Workflow migrated from an older Conductor version where expression language differed. Typo in a variable name in the expression. Input data shape changed so a previously-present field is now absent. GraalJS sandbox restrictions blocking certain operations.
Related errors
- Script not evaluated within %d seconds, interrupted.
- Script execution interrupted: %s
- Error evaluating the script `%s`
- Error evaluating the script `%s` at line %d
- Error evaluating the script %s
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/ce71af5670897bab.
Report an issue: GitHub.