conductor-oss/conductor · error · IllegalArgumentException
workflowDefinition must be either null, or WorkflowDef, or a
Error message
workflowDefinition must be either null, or WorkflowDef, or a valid DSL string
What it means
SubWorkflowParams.setWorkflowDefinition only accepts null, a WorkflowDef, a '${...}' DSL String, or a LinkedHashMap (converted to a WorkflowDef). Any other runtime type - number, boolean, plain HashMap, array/List - reaches the final else branch and throws this IllegalArgumentException.
Source
Thrown at common/src/main/java/com/netflix/conductor/common/metadata/workflow/SubWorkflowParams.java:167
*/
@JsonSetter("workflowDefinition")
public void setWorkflowDefinition(Object workflowDef) {
if (workflowDef == null) {
this.workflowDefinition = workflowDef;
} else if (workflowDef instanceof WorkflowDef) {
this.workflowDefinition = workflowDef;
} else if (workflowDef instanceof String) {
if (!(((String) workflowDef).startsWith("${"))
|| !(((String) workflowDef).endsWith("}"))) {
throw new IllegalArgumentException(
"workflowDefinition is a string, but not a valid DSL string");
} else {
this.workflowDefinition = workflowDef;
}
} else if (workflowDef instanceof LinkedHashMap) {
this.workflowDefinition = TaskUtils.convertToWorkflowDef(workflowDef);
} else {
throw new IllegalArgumentException(
"workflowDefinition must be either null, or WorkflowDef, or a valid DSL string");
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SubWorkflowParams that = (SubWorkflowParams) o;
return Objects.equals(getName(), that.getName())
&& Objects.equals(getVersion(), that.getVersion())
&& Objects.equals(getTaskToDomain(), that.getTaskToDomain())
&& Objects.equals(getWorkflowDefinition(), that.getWorkflowDefinition())
&& Objects.equals(idempotencyKey, that.idempotencyKey)View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Send workflowDefinition as a JSON object that deserializes to a WorkflowDef/LinkedHashMap.
- Omit the field (null) when you only need the sub-workflow name.
- Validate the payload type before submission - only object, string, or null are valid.
Example fix
// before: scalar/array - rejected
{"subWorkflowParam": {"workflowDefinition": 1}}
// after: object form
{"subWorkflowParam": {"workflowDefinition": {"name": "myWorkflow", "version": 1}}} Defensive patterns
Strategy: type-guard
Validate before calling
// Only allow object/string/null through to setWorkflowDefinition
static boolean isAcceptableWorkflowDefinitionType(Object v) {
if (v == null) return true;
return v instanceof WorkflowDef || v instanceof LinkedHashMap || v instanceof String;
} Type guard
// Type-guard: accept only the supported runtime types
static boolean isValidWorkflowDefinition(Object v) {
if (v == null) return true;
if (v instanceof WorkflowDef) return true;
if (v instanceof LinkedHashMap) return true;
return v instanceof String s && s.startsWith("${") && s.endsWith("}");
} Try / catch
// Catch the type error and reject the payload with context
try {
params.setWorkflowDefinition(raw);
} catch (IllegalArgumentException e) {
throw new BadRequestException(
"workflowDefinition has unsupported type: " + raw.getClass(), e);
} Prevention
- Send workflowDefinition as a JSON object, string, or omit it.
- Validate the field type before submission.
- Reject scalar/array payloads for workflowDefinition at the boundary.
When it happens
Trigger: Sending the 'workflowDefinition' JSON field as a scalar (int/boolean), an array, or a non-LinkedHashMap map type that Jackson deserializes to something other than LinkedHashMap.
Common situations: A client serializing the field incorrectly (e.g. a JSON number or array); passing a HashMap that Jackson maps to a different concrete type; malformed API payload from a generated SDK.
Related errors
- workflowDefinition is a string, but not a valid DSL string
- Invalid skill manifest JSON: {e.getMessage()}
- priority MUST be between 0 and 99 (inclusive)
- Model string cannot be null or empty
- Invalid model format: '%s'. Expected 'provider/model'.
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/c0381ecc108f6bfb.
Report an issue: GitHub.