flowable/flowable-engine · warning · FlowableObjectNotFoundException
The variable does not have a binary data stream.
Error message
The variable does not have a binary data stream.
What it means
FlowableObjectNotFoundException thrown when fetching raw variable data for a historic task whose variable is neither a byte-array (binary) nor a serializable value — i.e. it has no binary stream to return. The endpoint /cmmn-history/historic-task-instances/{taskId}/variables/{variableName}/data only serves byte[] and Serializable variables; plain string/number/boolean variables hit this error.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/task/HistoricTaskInstanceVariableDataResource.java:85
HttpServletResponse response) {
try {
byte[] result = null;
RestVariable variable = getVariableFromRequest(true, taskId, variableName, scope);
if (CmmnRestResponseFactory.BYTE_ARRAY_VARIABLE_TYPE.equals(variable.getType())) {
result = (byte[]) variable.getValue();
response.setContentType("application/octet-stream");
} else if (CmmnRestResponseFactory.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) {
// Re-throw IOException
throw new FlowableException("Unexpected exception getting variable data", ioe);
}
}
public RestVariable getVariableFromRequest(boolean includeBinary, String taskId, String variableName, String scope) {
RestVariableScope variableScope = RestVariable.getScopeFromString(scope);
HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery().taskId(taskId);
if (variableScope != null) {
if (variableScope == RestVariableScope.GLOBAL) {
taskQuery.includeProcessVariables();
} else {
taskQuery.includeTaskLocalVariables();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Use the plain variable endpoint GET .../variables/{variableName} instead of .../variables/{variableName}/data for non-binary variables
- Check the variable's type in the variable list response; only byte-array/serializable/binary types have raw data
- If you need the value of a string/number variable, read it from the normal REST variable representation (JSON)
- If the variable was expected to be binary, verify the process/case actually stored it as byte[] or Serializable
Example fix
// before
byte[] data = get("/cmmn-history/historic-task-instances/" + taskId + "/variables/" + name + "/data");
// after
RestVariable v = getVariable(taskId, name);
byte[] data = v.getType().isBinary() ? getRawData(taskId, name) : String.valueOf(v.getValue()).getBytes(); Defensive patterns
Strategy: validation
Validate before calling
const vars = await fetch(`/cmmn-history/historic-task-instances/${taskId}/variables`).then(r => r.json());
const v = vars.find(v => v.name === variableName);
if (!['byteArray','binary','serializable'].includes(v.type)) return v.value; // read via plain endpoint Type guard
function hasBinaryStream(variable) {
return variable != null && ['byteArray','binary','serializable'].includes(variable.type);
} Try / catch
try {
return await fetchVariableData(taskId, name);
} catch (e) {
if (String(e.message).includes('binary data stream')) return fetchPlainVariable(taskId, name);
throw e;
} Prevention
- List variables first and inspect the type field before calling the /data endpoint
- Only use /data for byte-array and serializable variables; use the plain variable endpoint otherwise
- Don't assume all task variables are file uploads
- Document in your client which variable types support raw data download
When it happens
Trigger: GET /cmmn-history/historic-task-instances/{taskId}/variables/{variableName}/data where the variable is a primitive type (String, Integer, Boolean, Date, etc.) with no byte-array or serializable payload.
Common situations: Trying to download a variable that is a JSON string or number as if it were a file upload; scripts that download all variables via the /data endpoint assuming all are binary; confusion between the plain variable endpoint and the raw-data endpoint.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unexpected exception getting variable data
- Historic task instance '' couldn't be found.
- The variable does not have a binary data stream.
- Variable '${restVariable.getName()}' has unsupported type: '
- Invalid variable scope: '${scope}'
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d1e756a9b7e57d8f.
Report an issue: GitHub.