karatelabs/karate · critical · RuntimeException

ext ' ': points at missing resource

Error message

ext '<name>': <key> points at missing resource: <BASE><path>

What it means

ReportAssets.requireResource validates at Suite boot that each declared js/css/asset path exists as a classpath resource under the BASE prefix. If getResourceAsStream returns null, the spec points at a resource that is not on the classpath, and the Suite fails at boot.

Solutions

  1. Check the exact path exists on the classpath: getClass().getClassLoader().getResource(BASE + path)
  2. Fix the path in the ReportAssets spec (paths are relative to BASE — see the message for the resolved full path)
  3. Move the file into the correct resources folder and rebuild
  4. If in a jar dependency, confirm the jar is on the runtime classpath

Example fix

// before
ReportAssets.named("my-ext").js("myext.js")
// after (file actually lives at BASE/ext/myext.js)
ReportAssets.named("my-ext").js("ext/myext.js")
Defensive patterns

Strategy: validation

Validate before calling

ClassLoader cl = Thread.currentThread().getContextClassLoader();
for (String p : List.of(jsPath, cssPath)) {
    if (cl.getResource("report/" + p) == null) throw new IllegalStateException("missing report resource: " + p);
}

Try / catch

try { suiteBoot(); } catch (RuntimeException e) { if (e.getMessage().contains("points at missing resource")) { log.error("Fix ReportAssets path; message shows the resolved BASE+path: {}", e.getMessage()); } throw e; }

Prevention

When it happens

Trigger: validateAndBind() with a js/css/asset path whose BASE + path does not resolve on the classpath — wrong path, missing file in src/main/resources, or file not copied into the build output.

Common situations: Typo in the resource path; resource in src/test/resources while the suite runs with only main resources; missing <resources> or sourceSets config; path missing the required BASE prefix (e.g. forgot 'ext/' style prefix handled by BASE).

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/3c86aed415006e25. Report an issue: GitHub.

Appendix: source

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

    }

    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);
        }
    }

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

View on GitHub (pinned to a22eb90246)