karatelabs/karate · error · java.lang.RuntimeException

java bridge not enabled

Error message

java bridge not enabled

What it means

The JsJava wrapper (the `Java` interop object) is constructed with a null ExternalBridge, meaning the JS engine was created without Java-bridge support enabled. The library throws immediately rather than failing later on first Java call, so misconfiguration is detected at setup time.

Solutions

  1. Enable the Java bridge when building the engine/context (pass an ExternalBridge to the builder).
  2. If interop should be unavailable, don't reference the `Java` global in scripts; gate such code behind a capability check.
  3. Check the engine-construction code path for a null/omitted bridge argument.
  4. If embedding via Karate, use the standard runtime entry points that wire the bridge automatically.

Example fix

// before
Context ctx = Context.forRoot(); // no bridge => Java global unusable
// after
Context ctx = Context.newBuilder().externalBridge(myBridge).build();
Defensive patterns

Strategy: validation

Validate before calling

if (bridge == null) throw new IllegalStateException("enable the Java bridge before using the Java global"); // or check at engine build time
Context ctx = Context.newBuilder().externalBridge(bridge).build();

Type guard

boolean javaInteropAvailable(Context ctx) { return ctx != null && ctx.getExternalBridge() != null; }

Try / catch

try { var t = Java.type("com.example.Foo"); } catch (RuntimeException e) { if (String(e.message).includes("java bridge not enabled")) { /* fall back or surface config error */ } else throw e; }

Prevention

When it happens

Trigger: Creating a JS Context/engine without registering an ExternalBridge (or with bridge disabled) and then referencing the `Java` global, e.g. Java.type(...).

Common situations: Embedding karate-js standalone (outside Karate's runtime) without wiring the Java bridge; running in a mode where Java interop is intentionally disabled (sandboxed scripts); forgetting the builder flag that enables interop after an upgrade.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/8f51d9d4df32f1f0. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsJava.java:32

 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package io.karatelabs.js;

public class JsJava implements SimpleObject {

    final ExternalBridge bridge;

    JsJava(ExternalBridge bridge) {
        if (bridge == null) {
            throw new RuntimeException("java bridge not enabled");
        }
        this.bridge = bridge;
    }

    @Override
    public Object jsGet(String name) {
        return switch (name) {
            case "type" -> (JsInvokable) args -> {
                String className = (String) args[0];
                // forType() returns null on ClassNotFoundException — that
                // null-as-sentinel contract is needed by PropertyAccess for
                // the dotted-FQN probe, so we keep it. But here the script
                // explicitly asked for this class; a null result must surface
                // as a real error rather than silently propagating and
                // failing later as "cannot read properties of null".
                ExternalAccess type = bridge.forType(className);
                if (type == null) {
                    throw JsErrorException.typeError("Java.type: class not found: " + className);

View on GitHub (pinned to a22eb90246)