karatelabs/karate · error · RuntimeException

ext ' ': failed reading

Error message

ext '<name>': failed reading <BASE><path> — <message>

What it means

requireResource wraps any IOException from reading the classpath resource during validation in a RuntimeException including the underlying message. Unlike the missing-resource case, the lookup itself failed (e.g. a closed/invalid classloader or jar I/O error).

Solutions

  1. Inspect the wrapped cause (e.getMessage()) to identify the I/O failure
  2. Rebuild/replace the corrupted jar and restart the JVM
  3. Restart the application server/framework that closed the classloader
  4. Retry after the shared/network filesystem recovers

Example fix

// after a rebuild, verify the jar is readable before running:
// jar tf app.jar | grep <BASE><path>
mvn clean package
Defensive patterns

Strategy: try-catch

Validate before calling

try (InputStream is = cl.getResourceAsStream(BASE + path)) { /* readable check before validateAndBind */ }

Try / catch

try { suiteBoot(); } catch (RuntimeException e) { if (e.getMessage().startsWith("ext '")) { log.error("report ext resource I/O failed: {}", e.getCause(), e); } throw e; }

Prevention

When it happens

Trigger: validateAndBind() where cl.getResourceAsStream(BASE + path) throws IOException — corrupted jar, closed classloader, or filesystem-backed classpath entry that disappeared mid-read.

Common situations: Jar file corrupted or truncated during a concurrent build; dev-mode classloader closed by a framework restart; NFS/network-mounted classpath entries temporarily unavailable.

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 karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/15d3b0ff8821feac. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/ReportAssets.java:228

            if (is == null) {
                throw new IOException("ext '" + name + "': resource vanished after validation: " + path);
            }
            Path parent = target.getParent();
            if (parent != null) {
                Files.createDirectories(parent);
            }
            Files.copy(is, target, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private void requireResource(ClassLoader cl, String path, String key) {
        try (InputStream is = cl.getResourceAsStream(BASE + path)) {
            if (is == null) {
                throw new RuntimeException("ext '" + name + "': " + key
                        + " points at missing resource: " + BASE + path);
            }
        } catch (IOException e) {
            throw new RuntimeException("ext '" + name + "': failed reading " + BASE + path + " — " + e.getMessage(), e);
        }
    }

    private static String stripStatic(String p) {
        return p.startsWith(STATIC_PREFIX) ? p.substring(STATIC_PREFIX.length()) : p;
    }
}

View on GitHub (pinned to a22eb90246)