flowable/flowable-engine · error · FlowableObjectNotFoundException

Task ' ' does not have a variable with name: ' '.

Error message

Task '${task.getId()}' does not have a variable with name: '${name}'.

What it means

Variable lookup failure in TaskVariableBaseResource.setVariable: while creating/updating, the check shows the task does not have a variable with the given name (in the relevant scope), which the requested operation requires.

Solutions

  1. Correct the variable name in the URL/body
  2. Add "variableScope": "global" (or local as appropriate) to target the scope where the variable lives
  3. Create the variable with POST if it should exist, or GET /runtime/tasks/{taskId}/variables to list what exists

Example fix

// before
PUT /runtime/tasks/123/variables/aprovedAmount  (typo, local scope)
// after
PUT /runtime/tasks/123/variables/approvedAmount
{"name": "approvedAmount", "value": true, "variableScope": "global"}
Defensive patterns

Strategy: validation

Validate before calling

const existing = await api.get(`/runtime/tasks/${taskId}/variables`); if (!existing.data.some(v => v.name === name && v.variableScope === scope)) { /* create via POST or fix name/scope */ }

Try / catch

try { await api.put(`/runtime/tasks/${taskId}/variables/${name}`, body); } catch (e) { if (e.response && e.response.status === 404) { await api.post(`/runtime/tasks/${taskId}/variables`, body); } else { throw e; } }

Prevention

When it happens

Trigger: PUT /runtime/tasks/{taskId}/variables/{variableName} where the name is absent from the task (or wrong scope: variable is on the execution/global scope while scope=local, or standalone task lacking a global).

Common situations: Typo in variable name; variable was created on the process/execution scope but updated with local scope; task completed and its variables were removed; different Flowable version/database where the variable was never set.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

            scope = RestVariableScope.LOCAL;
        }

        Object actualVariableValue = restResponseFactory.getVariableValue(restVariable);
        setVariable(task, restVariable.getName(), actualVariableValue, scope, isNew);

        return getVariableFromRequestWithoutAccessCheck(task, restVariable.getName(), scope.name(), false);
    }

    protected void setVariable(Task task, String name, Object value, RestVariableScope scope, boolean isNew) {
        // Create can only be done on new variables. Existing variables should
        // be updated using PUT
        boolean hasVariable = hasVariableOnScope(task, name, scope);
        if (isNew && hasVariable) {
            throw new FlowableException("Variable '" + name + "' is already present on task '" + task.getId() + "'.");
        }

        if (!isNew && !hasVariable) {
            throw new FlowableObjectNotFoundException("Task '" + task.getId() + "' does not have a variable with name: '" + name + "'.", null);
        }

        if (restApiInterceptor != null) {
            if (isNew) {
                restApiInterceptor.createTaskVariables(task, Collections.singletonMap(name, value), scope);
            } else {
                restApiInterceptor.updateTaskVariables(task, Collections.singletonMap(name, value), scope);
            }
        }

        if (scope == RestVariableScope.LOCAL) {
            taskService.setVariableLocal(task.getId(), name, value);
        } else {
            if (task.getExecutionId() != null) {
                // Explicitly set on execution, setting non-local variable on
                // task will override local-variable if exists
                runtimeService.setVariable(task.getExecutionId(), name, value);
            } else {

View on GitHub (pinned to d6d39ce1c6)