karatelabs/karate · error · RuntimeException

latest image is not a valid image

Error message

latest image is not a valid image

What it means

ImageComparison's constructor decodes the latest image with ImageIO.read(); when the bytes decode to null (data is present but not a recognized image format such as PNG/JPEG/BMP/GIF), it throws this error. This is a data-content check, not a file-existence check: the bytes were found but are not decodable by the JDK's ImageIO.

Solutions

  1. Verify the latest file is a real PNG/JPEG (open it locally or check magic bytes with a hex dump)
  2. Re-take the screenshot; ensure the driver/browser was ready before capture
  3. Convert unsupported formats (WebP/SVG/AVIF) to PNG before diffing
  4. Check for git-lfs pointer files or truncated downloads; re-download the artifact

Example fix

// before
image.diff({ baseline: 'base.png', latest: 'shot.webp' }) // ImageIO cannot decode WebP
// after (convert first, e.g. via build tooling) then:
image.diff({ baseline: 'base.png', latest: 'shot.png' })
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the latest image is a real PNG/JPEG by magic bytes
byte[] b = karate.readBytes('latest.png');
boolean png = b.length > 8 && (b[0]&0xFF)==0x89 && b[1]=='P';
if (!png) throw new RuntimeException("latest.png is not a valid PNG");

Try / catch

try {
    image.diff({ baseline: 'base.png', latest: 'latest.png' });
} catch (Exception e) {
    if (String.valueOf(e).contains("not a valid image")) {
        // log bytes length / re-capture screenshot and retry once
    }
}

Prevention

When it happens

Trigger: latest bytes exist but are not a valid image: empty file (0 bytes is caught as null read), corrupted/truncated download, HTML error page saved as .png, SVG (not supported by ImageIO), WebP/AVIF (unsupported by most JDKs), or a text placeholder written where a screenshot was expected.

Common situations: Screenshot step silently captured a blank/failed driver page; CI artifact download produced an error page; a WebP or SVG file passed where PNG was expected; image truncated by an incomplete file copy or git-lfs pointer file not materialized.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/12a83223f599f2b2. Report an issue: GitHub.

Appendix: source

Thrown at karate-image/src/main/java/io/karatelabs/ext/image/ImageComparison.java:111

    private final Map<String, Object> options;
    private final Map<String, Object> result;

    private ImageComparison(
            byte[] baselineImg, byte[] latestImg, Map<String, Object> options, Map<String, Object> defaultOptions) {

        this.options = options;
        this.result = new HashMap<>();
        this.configure(defaultOptions);

        this.baselineMissing = baselineImg == null || baselineImg.length == 0;

        BufferedImage baselineImage;
        BufferedImage latestImage;

        try {
            latestImage = ImageIO.read(new ByteArrayInputStream(latestImg));
            if (latestImage == null) {
                throw new RuntimeException("latest image is not a valid image");
            }

            baselineImage = baselineMissing ? latestImage : ImageIO.read(new ByteArrayInputStream(baselineImg));
            if (baselineImage == null) {
                throw new RuntimeException("baseline image is not a valid image");
            }
        } catch (IOException e) {
            logger.error("image comparison failed while reading images: {}", e.getMessage());
            throw new RuntimeException(e);
        }

        this.height = baselineImage.getHeight();
        this.width = baselineImage.getWidth();

        int latestHeight = latestImage.getHeight();
        int latestWidth = latestImage.getWidth();

        if (width != latestWidth || height != latestHeight) {

View on GitHub (pinned to a22eb90246)