flowable/flowable-engine · error · FlowableException

Error reading app resource

Error message

Error reading app resource

What it means

FlowableException (wrapping the Jackson cause) thrown by AppResourceConverterImpl.convertAppResourceToModel when the app resource bytes cannot be deserialized into a BaseAppModel. The app resource is expected to be valid JSON matching the app model schema.

Source

Thrown at modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/deployer/AppResourceConverterImpl.java:34

import org.flowable.app.api.repository.AppResourceConverter;
import org.flowable.common.engine.api.FlowableException;

import tools.jackson.databind.ObjectMapper;

public class AppResourceConverterImpl implements AppResourceConverter {

    protected ObjectMapper objectMapper;

    public AppResourceConverterImpl(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public AppModel convertAppResourceToModel(byte[] appResourceBytes) {
        try {
            return objectMapper.readValue(appResourceBytes, BaseAppModel.class);
        } catch (Exception e) {
            throw new FlowableException("Error reading app resource", e);
        }
    }

    @Override
    public String convertAppModelToJson(AppModel appModel) {
        try {
            return objectMapper.writeValueAsString(appModel);
        } catch (Exception e) {
            throw new FlowableException("Error writing app model " + appModel.getKey() + " to json", e);
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the bytes are the JSON app resource (valid UTF-8 JSON with model name/fields), not a zip archive
  2. Validate the JSON with a linter or by parsing it before conversion
  3. Check for truncation/encoding issues in how the resource was read (read bytes fully, correct charset)
  4. If cause is missing fields, align the JSON with BaseAppModel structure

Example fix

// before
byte[] bytes = Files.readAllBytes(Path.of("my-app.zip")); // binary zip
AppModel m = converter.convertAppResourceToModel(bytes);
// after
byte[] bytes = extractAppJsonFromZip(Path.of("my-app.zip")); // get inner app JSON
AppModel m = converter.convertAppResourceToModel(bytes);
Defensive patterns

Strategy: validation

Validate before calling

String s = new String(bytes, StandardCharsets.UTF_8).trim();
if (s.isEmpty() || (!s.startsWith("{") && !s.startsWith("["))) {
    throw new IllegalArgumentException("App resource must be JSON, not binary/zip content");
}

Try / catch

try {
    AppModel model = converter.convertAppResourceToModel(bytes);
} catch (FlowableException e) {
    logger.error("Invalid app resource JSON", e.getCause());
    throw new IllegalArgumentException("Malformed app resource", e);
}

Prevention

When it happens

Trigger: Passing a byte[] to convertAppResourceToModel that is not valid JSON — e.g. binary .app/zip content, an empty array, truncated file, or JSON missing required model fields.

Common situations: Deploying a .zip renamed to .app instead of a JSON app resource; file saved with wrong encoding or corrupted in transit; hand-edited app JSON with syntax errors; passing an app archive's binary entry instead of the app.json resource.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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