conductor-oss/conductor · error · TerminateWorkflowException
Input has to be a JSON object: %s
Error message
Input has to be a JSON object: %s
What it means
Thrown by ValueParamEvaluator.evaluate() when the input object passed to the evaluator is not a Map. The value-param evaluator extracts a value by key from a JSON object (Map); it cannot operate on a scalar, list, or other type. This is used by SWITCH tasks with evaluatorType 'value-param'. A TerminateWorkflowException means the workflow is terminated with this error — it does not retry.
Source
Thrown at core/src/main/java/com/netflix/conductor/core/execution/evaluators/ValueParamEvaluator.java:40
@Component(ValueParamEvaluator.NAME)
public class ValueParamEvaluator implements Evaluator {
public static final String NAME = "value-param";
private static final Logger LOGGER = LoggerFactory.getLogger(ValueParamEvaluator.class);
@SuppressWarnings("unchecked")
@Override
public Object evaluate(String expression, Object input) {
LOGGER.debug("ValueParam evaluator -- evaluating: {}", expression);
if (input instanceof Map) {
Object result = ((Map<String, Object>) input).get(expression);
LOGGER.debug("ValueParam evaluator -- result: {}", result);
return result;
} else {
String errorMsg = String.format("Input has to be a JSON object: %s", input.getClass());
LOGGER.error(errorMsg);
throw new TerminateWorkflowException(errorMsg);
}
}
}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Inspect the SWITCH task's input parameters — ensure the value feeding the evaluator resolves to a JSON object (Map) at runtime.
- Fix the upstream task so its output is a JSON object, not a scalar or array.
- Change the evaluatorType to one that handles non-Map input, or restructure the input mapping.
- Add a JSONata or Javascript expression upstream to coerce the value into an object before it reaches the SWITCH task.
Example fix
// workflow definition (before) — $.items is an array
{
"type": "SWITCH",
"evaluatorType": "value-param",
"expression": "items",
"inputParameters": { "items": "${workflow.output.items}" }
}
// after — extract a specific object key from the array
{
"type": "SWITCH",
"evaluatorType": "value-param",
"expression": "status",
"inputParameters": { "status": "${task1.output.status}" }
} Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure SWITCH value-param input is a Map
Object inputForEval = taskInput.get(expression);
if (!(inputForEval instanceof Map)) {
throw new IllegalStateException(
"Expected JSON object for value-param, got: " + inputForEval.getClass());
} Type guard
private boolean isJsonMap(Object input) {
return input instanceof Map;
} Prevention
- Verify upstream task outputs are JSON objects when feeding value-param evaluators.
- Test workflow definitions with sample runtime data to catch type mismatches early.
- Use defensive expressions to coerce types before the SWITCH task.
When it happens
Trigger: A SWITCH task configured with evaluatorType 'value-param' where the expression resolves against task input that is a List, String, or null instead of a JSON object. The taskInput map provided to the evaluator is not a Map at runtime.
Common situations: A previous task outputs an array or scalar where the SWITCH task expects a JSON object. The input parameter mapping in the workflow definition produces a non-Map value due to a malformed ${...} expression. A JSON field that is expected to be an object is actually a string in the runtime data.
Related errors
- No evaluator registered for type: %s
- Tasks could not be dynamically forked due to invalid input:
- Input to the dynamically forked tasks is not a map -> expect
- Empty 'evaluatorType' in INLINE task's input parameters. A n
- Unknown evaluator '%s' in INLINE task.
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/ba0858ee71be9737.
Report an issue: GitHub.