flowable/flowable-engine · error · FlowableIllegalArgumentException

Cannot set global variables on task

Error message

Cannot set global variables on task '${task.getId()}', task is not part of process.

What it means

Like single-variable creation, the bulk endpoint cannot set global-scope variables on a standalone task: with a null executionId there is no process scope to hold them, so FlowableIllegalArgumentException is thrown.

Solutions

  1. Use "variableScope": "local" for all entries on standalone tasks
  2. Split the request so global variables go to the execution/process endpoints instead
  3. Guard: check the task is part of a process before sending global-scope batches

Example fix

// before
[{"name":"a","value":1,"variableScope":"global"}]  // standalone task
// after
[{"name":"a","value":1,"variableScope":"local"}]
Defensive patterns

Strategy: type-guard

Validate before calling

const task = await api.get(`/runtime/tasks/${taskId}`); if (!task.data.executionId && variables.some(v => (v.variableScope || 'local') === 'global')) { throw new Error('Global variables not allowed on standalone task'); }

Type guard

function batchAllowed(task, vars) { return Boolean(task.executionId) || !vars.some(v => (v.variableScope || 'local') === 'global'); }

Try / catch

try { await api.post(`/runtime/tasks/${taskId}/variables`, vars); } catch (e) { if (e.response && e.response.status === 400 && /global variables/.test(e.response.data.message || '')) { await api.post(`/runtime/tasks/${taskId}/variables`, vars.map(v => ({...v, variableScope: 'local'}))); } else { throw e; } }

Prevention

When it happens

Trigger: POST /runtime/tasks/{taskId}/variables with sharedScope=global (any/all entries global) on a task whose executionId is null (standalone task, or process already terminated).

Common situations: Standalone tasks created via the REST API; batches grouped into a global scope by one stray entry; code paths shared between process and standalone tasks.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskVariableCollectionResource.java:199

            if (!variablesToSet.isEmpty()) {
                if (restApiInterceptor != null) {
                    restApiInterceptor.createTaskVariables(task, variablesToSet, sharedScope);
                }

                Map<String, Object> setVariables;
                if (sharedScope == RestVariableScope.LOCAL) {
                    taskService.setVariablesLocal(task.getId(), variablesToSet);
                    setVariables = taskService.getVariablesLocal(task.getId(), variablesToSet.keySet());
                } else {
                    if (task.getExecutionId() != null) {
                        // Explicitly set on execution, setting non-local
                        // variables on task will override local-variables if
                        // exists
                        runtimeService.setVariables(task.getExecutionId(), variablesToSet);
                        setVariables = runtimeService.getVariables(task.getExecutionId(), variablesToSet.keySet());
                    } else {
                        // Standalone task, no global variables possible
                        throw new FlowableIllegalArgumentException("Cannot set global variables on task '" + task.getId() + "', task is not part of process.");
                    }
                }

                for (RestVariable inputVariable : inputVariables) {
                    String variableName = inputVariable.getName();
                    Object variableValue = setVariables.get(variableName);
                    resultVariables.add(restResponseFactory.createRestVariable(variableName, variableValue, varScope, task.getId(), RestResponseFactory.VARIABLE_TASK, false));
                }
            }
        }

        return result;
    }

    @ApiOperation(value = "Delete all local variables on a task", tags = { "Tasks" }, code = 204)
    @ApiResponses(value = {
            @ApiResponse(code = 204, message = "Indicates all local task variables have been deleted. Response-body is intentionally empty."),
            @ApiResponse(code = 404, message = "Indicates the requested task was not found.")

View on GitHub (pinned to d6d39ce1c6)