flowable/flowable-engine · error · FlowableIllegalArgumentException

Invalid variable scope: '${scope}'

Error message

Invalid variable scope: '${scope}'

What it means

RestVariable.getScopeFromString converts a scope string ("global"/"local", case-insensitive) into a RestVariableScope enum. Any non-null string that matches no scope name is rejected with FlowableIllegalArgumentException; null is allowed and yields null.

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/engine/variable/RestVariable.java:65

        String scope = null;
        if (variableScope != null) {
            scope = variableScope.name().toLowerCase();
        }
        return scope;
    }

    public void setScope(String scope) {
        setVariableScope(getScopeFromString(scope));
    }

    public static RestVariableScope getScopeFromString(String scope) {
        if (scope != null) {
            for (RestVariableScope s : RestVariableScope.values()) {
                if (s.name().equalsIgnoreCase(scope)) {
                    return s;
                }
            }
            throw new FlowableIllegalArgumentException("Invalid variable scope: '" + scope + "'");
        } else {
            return null;
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use only "global" or "local" as the scope value
  2. Omit the scope field (or send null) when default scoping is desired
  3. Trim user-supplied input before passing to setScope
  4. Add client-side validation mapping domain scope concepts to the two allowed names

Example fix

// before
{"name":"x","scope":"case","value":1}
// after
{"name":"x","scope":"local","value":1}
Defensive patterns

Strategy: validation

Validate before calling

if (scope != null && !scope.equalsIgnoreCase("global") && !scope.equalsIgnoreCase("local")) {
    throw new IllegalArgumentException("scope must be 'global' or 'local'");
}

Type guard

RestVariableScope safeScope(String s) {
    return (s == null || s.equalsIgnoreCase("global") || s.equalsIgnoreCase("local"))
        ? RestVariable.getScopeFromString(s) : null;
}

Try / catch

try {
    restVariable.setScope(scopeInput);
} catch (FlowableIllegalArgumentException e) {
    restVariable.setScope(null); // default scope
}

Prevention

When it happens

Trigger: Setting a variable's "scope" field in REST requests (or via RestVariable.setScope) to something other than global/local, e.g. "process", "case", "Global ".

Common situations: Clients confusing scope vocabularies from other Flowable/Activiti APIs; whitespace or casing assumptions (casing is fine, trailing spaces are not); templated payloads with placeholder scope values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/36a86ce4c7eb327b. Report an issue: GitHub.