flowable/flowable-engine · error · FlowableObjectNotFoundException

The variable does not have a binary data stream.

Error message

The variable does not have a binary data stream.

What it means

Thrown by the Flowable REST history API when a request asks for the binary data of a historic variable instance (by variable instance id) but the value is not a byte array that can be streamed. Only binary variables expose a /data endpoint; primitives and Strings are returned in the JSON representation instead. Raised as FlowableObjectNotFoundException since no binary stream exists for the variable.

Source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricVariableInstanceDataResource.java:83

    @ResponseBody
    public byte[] getVariableData(@ApiParam(name = "varInstanceId") @PathVariable("varInstanceId") String varInstanceId, HttpServletResponse response) {
        try {
            byte[] result = null;
            RestVariable variable = getVariableFromRequest(true, varInstanceId);
            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) {
            // Re-throw IOException
            throw new FlowableException("Unexpected exception getting variable data", ioe);
        }
    }

    public RestVariable getVariableFromRequest(boolean includeBinary, String varInstanceId) {
        HistoricVariableInstance varObject = historyService.createHistoricVariableInstanceQuery().id(varInstanceId).singleResult();

        if (varObject == null) {
            throw new FlowableObjectNotFoundException("Historic variable instance '" + varInstanceId + "' could not be found.", VariableInstanceEntity.class);
        } else {
            
            if (restApiInterceptor != null) {
                restApiInterceptor.accessHistoryVariableInfoById(varObject);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check the variable's type via GET /history/historic-variable-instances/{varInstanceId} and only request /data for type 'binary' (valueUrl present)
  2. Read non-binary values directly from the variable JSON 'value' field
  3. If the value should have been binary, fix the writer to store byte[] variables
  4. Handle 404/FlowableObjectNotFoundException on the client by falling back to the JSON variable endpoint

Example fix

// before
byte[] raw = get('/history/historic-variable-instances/' + id + '/data')
// after
const meta = await get('/history/historic-variable-instances/' + id)
if (meta.data.valueUrl) {
  return get(meta.data.valueUrl, { responseType: 'arraybuffer' })
}
return meta.data.value
Defensive patterns

Strategy: validation

Validate before calling

const meta = await api.get(`/history/historic-variable-instances/${id}`);
if (!meta.data.valueUrl) throw new SkipBinaryDownloadError(meta.data.type);

Type guard

function hasBinaryStream(meta) { return Boolean(meta && typeof meta.valueUrl === 'string'); }

Try / catch

try { return await api.get(`${baseUrl}/data`, {responseType:'arraybuffer'}); } catch (e) { if (e.response && e.response.status === 404) return (await api.get(baseUrl)).data.value; throw e; }

Prevention

When it happens

Trigger: GET /history/historic-variable-instances/{varInstanceId}/data when the variable's type is not 'binary' (e.g. string, long, date, serializable handled via JSON), so getVariableData hits the else branch and throws.

Common situations: Generic download clients hitting /data for every variable id collected from the variables list endpoint; tests that assume all historic variables are attachments; migration scripts exporting variable blobs that include non-binary columns.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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