flowable/flowable-engine · error · FlowableException

Error getting variable ${variableName}

Error message

Error getting variable ${variableName}

What it means

FlowableException wrapping an IOException thrown when reading or serializing the variable's binary data stream fails during getVariableData. It indicates an I/O problem (stream read/serialization failure), not that the variable is missing.

Source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionVariableDataResource.java:84

            if (RestResponseFactory.BYTE_ARRAY_VARIABLE_TYPE.equals(variable.getType())) {
                result = (byte[]) variable.getValue();
                response.setContentType("application/octet-stream");

            } else if (RestResponseFactory.SERIALIZABLE_VARIABLE_TYPE.equals(variable.getType())) {
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                ObjectOutputStream outputStream = new ObjectOutputStream(buffer);
                outputStream.writeObject(variable.getValue());
                outputStream.close();
                result = buffer.toByteArray();
                response.setContentType("application/x-java-serialized-object");

            } else {
                throw new FlowableObjectNotFoundException("The variable does not have a binary data stream.", null);
            }
            return result;

        } catch (IOException ioe) {
            throw new FlowableException("Error getting variable " + variableName, ioe);
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check the wrapped IOException cause in the server logs for the root failure
  2. Re-save the variable value if the stored serialized object is corrupt or its class version changed
  3. Ensure all classes stored in serializable variables are on the REST server's classpath with matching serialVersionUID
  4. Retry the request; if it persists, avoid Java-serialized variables and use byte-array variables

Example fix

// before
runtimeService.setVariable(executionId, "payload", new LegacyDto())
// after
runtimeService.setVariable(executionId, "payload", dtoBytes) // byte[] variable
Defensive patterns

Strategy: retry

Validate before calling

// ensure the variable exists and is serializable-safe before reading
const v = await getExecutionVariables(id);
if (v.find(x => x.name === name && x.type === "serializable")) verifyClassesOnServerClasspath();

Try / catch

try { return await fetchVariableData(id, name); }
catch (e) { if (isRetryable(e)) return retry(fetchVariableData, [id, name], 2); throw e; }

Prevention

When it happens

Trigger: GET /runtime/executions/{id}/variables/{name}/data where writing the variable value to the output stream or reading the request fails with an IOException, e.g. corrupt serializable payload or broken stream/pipe.

Common situations: Corrupted Java-serialized objects stored as serializable variables (e.g. class version mismatch on deserialization), client disconnecting mid-download, large variable exceeding stream/memory limits.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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