flowable/flowable-engine · error · ActivitiException

Error while reading process diagram image.

Error message

Error while reading process diagram image.

What it means

getDiagramBoundsFromImage reads the process diagram image via ImageIO.read to determine its pixel bounds for offset calculations. If the stream cannot be read or decoded as an image (IOException), an ActivitiException is thrown.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/diagram/ProcessDiagramLayoutFactory.java:187

        DiagramNode diagramBounds = new DiagramNode("BPMNDiagram");
        diagramBounds.setX(minX);
        diagramBounds.setY(minY);
        diagramBounds.setWidth(maxX - minX);
        diagramBounds.setHeight(maxY - minY);
        return diagramBounds;
    }

    protected DiagramNode getDiagramBoundsFromImage(InputStream imageStream) {
        return getDiagramBoundsFromImage(imageStream, 0, 0);
    }

    protected DiagramNode getDiagramBoundsFromImage(InputStream imageStream, int offsetTop, int offsetBottom) {
        BufferedImage image;
        try {
            image = ImageIO.read(imageStream);
        } catch (IOException e) {
            throw new ActivitiException("Error while reading process diagram image.", e);
        }
        DiagramNode diagramBoundsImage = getDiagramBoundsFromImage(image, offsetTop, offsetBottom);
        return diagramBoundsImage;
    }

    protected DiagramNode getDiagramBoundsFromImage(BufferedImage image, int offsetTop, int offsetBottom) {
        int width = image.getWidth();
        int height = image.getHeight();

        Map<Integer, Boolean> rowIsWhite = new TreeMap<>();
        Map<Integer, Boolean> columnIsWhite = new TreeMap<>();

        for (int row = 0; row < height; row++) {
            if (!rowIsWhite.containsKey(row)) {
                rowIsWhite.put(row, true);
            }
            if (row <= offsetTop || row > image.getHeight() - offsetBottom) {
                rowIsWhite.put(row, true);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the image file is valid and decodable by ImageIO (PNG/JPEG/GIF)
  2. Reset or reopen the InputStream before the call
  3. Check image format support for your JDK (some formats like TIFF need extra libraries)
Defensive patterns

Strategy: validation

Validate before calling

try {
    BufferedImage img = ImageIO.read(new File(imagePath));
    if (img == null) throw new IllegalStateException("Not a decodable image: " + imagePath);
} catch (IOException e) { throw new IllegalStateException("Unreadable image", e); }

Try / catch

try {
    bounds = factory.getProcessDiagramLayout(bpmnStream, imageStream);
} catch (org.activiti.engine.ActivitiException e) {
    if (e.getMessage().contains("reading process diagram image")) {
        // supply a valid PNG/JPEG stream or skip image-based bounds
    }
}

Prevention

When it happens

Trigger: getDiagramBoundsFromImage is called with an InputStream whose content is not a readable image format or whose stream throws IOException during read.

Common situations: Passing a corrupt/empty image file; supplying an unsupported image format; stream already consumed by a previous read.

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/720e962c8c328899. Report an issue: GitHub.