karatelabs/karate · critical · RuntimeException
ext ' ': ReportAssets.js(...) is required
Error message
ext '<name>': ReportAssets.js(...) is required
What it means
ReportAssets.validateAndBind checks each registered report extension spec at Suite boot: a spec without a JS entry is invalid because the extension has no client-side code to run. The failure is deliberately thrown at boot so misconfigured extensions fail the whole Suite early.
Solutions
- Call .js("classpath:my-ext.js") (or relative path) on the ReportAssets spec before registration
- Verify the js path points at an existing classpath resource — the next validation step requires it
- Check that every registered spec in registerReportAssets completes its builder chain with js(...)
Example fix
// before
ReportAssets.named("my-ext").css("style.css")
// after
ReportAssets.named("my-ext").js("ext/my-ext.js").css("ext/style.css") Defensive patterns
Strategy: validation
Validate before calling
void check(ReportAssets a) { if (!a.toString().contains("js")) throw new IllegalStateException("spec missing js()"); }
// simpler: enforce in your own builder wrapper that js(...) is always called before registerReportAssets Try / catch
try { suite.registerReportAssets(specs); } catch (RuntimeException e) { if (e.getMessage().contains("ReportAssets.js(...) is required")) { log.error("Extension spec missing js(): {}", e.getMessage()); } throw e; } Prevention
- Build ReportAssets specs through a shared helper that always appends .js(...)
- Add a unit test asserting every registered spec has a js path
- Fail fast in your own config loader when the js path property is absent
When it happens
Trigger: Registering a ReportAssets spec via registerReportAssets without calling .js(path), or calling js("") / js(" ").
Common situations: Building the spec conditionally and skipping the js() call; renaming an extension and forgetting its JS registration; copying a spec template with the js() line removed.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- ext ' ': points at missing resource
- embed(): each 'parts' entry must be an object
- embed(): each part needs a 'role'
- embed(): part ' ' needs 'data', 'path', or 'url
- ReportAssets.named: name is null or empty
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/186c46088cfbdffe.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/ReportAssets.java:169
/** The ext-supplied CTA label, or null if this ext registered none. */
public String ctaLabel() {
return ctaLabel;
}
/** The ext-supplied CTA href, or null if this ext registered none. */
public String ctaHref() {
return ctaHref;
}
/**
* Validate the spec against {@code classLoader} and bind it for later copying.
* Throws (failing the Suite at boot) when {@code js} is unset or a referenced
* resource is missing.
*/
void validateAndBind(ClassLoader classLoader) {
if (js == null || js.isBlank()) {
throw new RuntimeException("ext '" + name + "': ReportAssets.js(...) is required");
}
requireResource(classLoader, js, "js");
if (css != null) {
requireResource(classLoader, css, "css");
}
for (String a : assets) {
requireResource(classLoader, a, "asset");
}
for (Page p : pages) {
if (p.href() != null) {
requireResource(classLoader, p.href(), "page");
}
}
this.classLoader = classLoader;
}
/**
* Copy the declared assets (JS, optional CSS, page HTML) into {@code extDir}View on GitHub (pinned to a22eb90246)