karatelabs/karate · error · IllegalArgumentException
registerGlobal: name is null or empty
Error message
registerGlobal: name is null or empty
What it means
Suite.registerGlobal(String, Object) validates the global name before storing it. Karate throws this IllegalArgumentException at Suite boot when the name argument is null or a blank string, because a global binding without a name can never be referenced from scripts. Throwing loud at boot prevents silently registering an unusable global.
Solutions
- Check the value passed as the name argument and ensure it is a non-null, non-blank String literal or constant
- If the name comes from config/env, add a null/blank check with a clear failure message before calling registerGlobal
- If overloading confusion is possible, verify you are calling the (String, Object) overload with arguments in the right order
Example fix
// before
suite.registerGlobal(System.getProperty("ext.global.name"), new MyHelper());
// after
String name = System.getProperty("ext.global.name");
if (name == null || name.isBlank()) throw new IllegalArgumentException("ext.global.name must be set");
suite.registerGlobal(name, new MyHelper()); Defensive patterns
Strategy: validation
Validate before calling
if (name == null || name.isBlank()) throw new IllegalArgumentException("global name required");
suite.registerGlobal(name, instance); Type guard
boolean usableName(String n) { return n != null && !n.isBlank(); } Prevention
- Use a compile-time constant for global names
- Validate names sourced from config/env before registration
- Register globals in one reviewed init method
When it happens
Trigger: Calling suite.registerGlobal(null, myInstance) or suite.registerGlobal("", myInstance) (or a whitespace-only name like " ") before running the suite.
Common situations: The name is computed dynamically (e.g. from a config value, environment variable, or a constants class where the constant itself is null); refactoring renamed the constant away leaving null; the caller passes a variable initialized later.
Related errors
- ext global '' collides with built-in ''
- at least one feature file is required
- body() needs at least one argument
- boot.classpath(' '): expected a directory RELATIVE to the…
- boot.classpath: dir is null — pass a project-relative…
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/bd18eba6fee39461.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/Suite.java:756
* Built-in JS-scope names an ext global may not shadow. Registration of a
* colliding ext global fails the Suite loud at boot (see EXT.md § Ext globals).
*/
// `match` is intentionally NOT reserved — core no longer ships a global `match` (assertions are the
// Gherkin `match` keyword + `karate.match`); a consumer may register its own `match` global.
private static final Set<String> RESERVED_GLOBAL_NAMES = Set.of("karate", "read", "driver");
/**
* Register an ext global under {@code name}, seeded into every scenario's JS
* scope before {@code karate-config.js} evaluates. Called by an {@link Ext}
* from {@link Ext#onBoot(Suite)}; the instance is typically a
* {@link io.karatelabs.js.SimpleObject} so members cross into JS natively
* (no reflection). Throws — and so fails the Suite at boot — when the name is
* blank or collides with a built-in global ({@code karate}, {@code read},
* {@code match}, {@code driver}).
*/
public void registerGlobal(String name, Object instance) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("registerGlobal: name is null or empty");
}
if (RESERVED_GLOBAL_NAMES.contains(name)) {
throw new RuntimeException("ext global '" + name + "' collides with built-in '" + name + "'");
}
globals.put(name, instance);
}
/**
* Register a <em>per-scenario</em> ext global: the {@link ExtGlobalFactory} is
* invoked once per scenario at seed time to mint a fresh instance bound with the
* scenario's {@link KarateJsContext}. Prefer this over the singleton
* {@link #registerGlobal(String, Object)} when the global carries per-scenario
* mutable state or needs runtime / path access — see {@link ExtGlobalFactory}.
*/
public void registerGlobal(String name, ExtGlobalFactory factory) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("registerGlobal: name is null or empty");
}View on GitHub (pinned to a22eb90246)