karatelabs/karate · error · IOException

ext ' ': resource vanished after validation

Error message

ext '<name>': resource vanished after validation: <path>

What it means

During report generation, ReportAssets.copyResource finds that a classpath resource which passed earlier validation can no longer be opened. This is an IOException thrown mid-copy, indicating the classpath changed between validation and copy (or the resource was never addressable through this classloader).

Solutions

  1. Re-run validateAndBind / restart the Suite after any rebuild so validation and copy use the same classpath
  2. Confirm the resource exists in the built artifact: jar tf app.jar | grep <path>
  3. Use the same ClassLoader for validation and copy (e.g. Thread.currentThread().getContextClassLoader())
  4. Ensure build config (Maven/Gradle resources) includes the report assets directory

Example fix

// before (validate with one loader, copy with another)
assets.validateAndBind(MyApp.class.getClassLoader());
// after
ClassLoader cl = Thread.currentThread().getContextClassLoader();
assets.validateAndBind(cl);
// ... later, copyTo must use the same cl
Defensive patterns

Strategy: fallback

Validate before calling

boolean present(ClassLoader cl, String path) { return cl.getResource(BASE + path) != null; }

Try / catch

try { assets.copyTo(targetDir); } catch (IOException e) { if (e.getMessage().contains("resource vanished")) { log.warn("classpath changed mid-run; revalidating"); assets.validateAndBind(cl); assets.copyTo(targetDir); } else throw e; }

Prevention

When it happens

Trigger: copyTo() copying a previously validated js/css/asset whose getResourceAsStream now returns null — e.g. jar rebuilt or classloader swapped between validateAndBind and report generation.

Common situations: Fat-jar shading that strips resources; the resource living in a different jar not on the runtime classpath; hot-reload/dev mode where target/classes was cleaned mid-run; module/classloader isolation (app server) hiding the resource from this ClassLoader.

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

Appendix: source

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

        Files.createDirectories(extDir);
        copyResource(js, extDir.resolve(stripStatic(js)));
        if (css != null) {
            copyResource(css, extDir.resolve(stripStatic(css)));
        }
        for (String a : assets) {
            copyResource(a, extDir.resolve(stripStatic(a)));
        }
        for (Page p : pages) {
            if (p.href() != null) {
                copyResource(p.href(), extDir.resolve(p.href()));
            }
        }
    }

    private void copyResource(String path, Path target) throws IOException {
        try (InputStream is = classLoader.getResourceAsStream(BASE + path)) {
            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);
        }

View on GitHub (pinned to a22eb90246)