conductor-oss/conductor · error · IllegalArgumentException

Expression is not well formatted: %s

Error message

Expression is not well formatted: %s

What it means

Thrown during workflow definition validation (WorkflowTaskTypeConstraint) when a DECISION task's caseExpression or a SWITCH task's expression (with evaluatorType 'javascript') fails a syntax-only check by ScriptEvaluator.validateScriptSyntax (GraalVM Context.parse). It signals a malformed JavaScript expression that cannot even be parsed. Surfaced as a constraint violation at registration/update time (HTTP 400).

Source

Thrown at core/src/main/java/com/netflix/conductor/validations/WorkflowTaskTypeConstraint.java:197

                                    ee.getMessage() + ", taskType: DECISION taskName %s",
                                    workflowTask.getName());
                    context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
                    valid = false;
                }
            }

            return valid;
        }

        private void validateScriptExpression(
                String expression, Map<String, Object> inputParameters) {
            try {
                // Syntax check only: at registration time inputParameters still holds unresolved
                // ${...} placeholders, so evaluating the expression would throw ReferenceError
                // for any runtime-bound variable and reject valid definitions (issue #1311).
                ScriptEvaluator.validateScriptSyntax(expression);
            } catch (Exception e) {
                throw new IllegalArgumentException(
                        String.format("Expression is not well formatted: %s", e.getMessage()));
            }
        }

        private boolean isSwitchTaskValid(
                WorkflowTask workflowTask, ConstraintValidatorContext context) {
            boolean valid = true;
            if (workflowTask.getEvaluatorType() == null) {
                String message =
                        String.format(
                                PARAM_REQUIRED_STRING_FORMAT,
                                "evaluatorType",
                                TaskType.SWITCH,
                                workflowTask.getName());
                context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
                valid = false;
            } else if (workflowTask.getExpression() == null) {
                String message =

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Test the expression in a JS parser/node REPL with placeholders substituted by sample values.
  2. Ensure parentheses/braces are balanced and strings terminated.
  3. For SWITCH tasks confirm evaluatorType is 'javascript' and expression is pure JS (minus ${} placeholders which are resolved before evaluation at runtime).
  4. Note: only syntax is checked at registration; runtime ReferenceErrors from unbound variables are NOT caught here (issue #1311).

Example fix

// before - DECISION task with broken expression
{
  "name": "check",
  "taskReferenceName": "check_ref",
  "type": "DECISION",
  "caseExpression": "$.amount >"
}

// after - complete, valid boolean expression
{
  "name": "check",
  "taskReferenceName": "check_ref",
  "type": "DECISION",
  "caseExpression": "$.amount > 100"
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the JS expression syntax before registration
try {
    com.netflix.conductor.core.events.ScriptEvaluator.validateScriptSyntax(expression);
} catch (IllegalArgumentException e) {
    // fix the expression
}

Try / catch

try {
    metadataService.registerWorkflowDef(def);
} catch (ValidationException e) {
    // e contains 'Expression is not well formatted' for bad JS
}

Prevention

When it happens

Trigger: Registering or updating a workflow whose DECISION.caseExpression or SWITCH.expression (evaluatorType=javascript) contains a JavaScript syntax error (unbalanced parens, stray token, unterminated string). validateScriptSyntax rethrows only PolyglotException where isSyntaxError() is true.

Common situations: Hand-writing JS expressions like '$.amount >' (incomplete) or '${ if($.x) } ' (invalid placeholder splice); copy-paste introducing a stray character; expecting a different expression dialect; mixing ${} interpolation with raw JS that breaks the parsed form.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/a4dbb15fd549e6ee. Report an issue: GitHub.