karatelabs/karate · error · JsErrorException

no such api on Java

Error message

no such api on Java: {name}

What it means

The Java bridge object in JS only exposes a fixed set of named APIs (e.g. 'type', 'to'); requesting an unknown member name throws this TypeError from the switch default in jsGet. It means the script accessed Java.<name> for a name the bridge does not implement.

Solutions

  1. Use Java.type('fully.qualified.ClassName') to obtain the class, then call static members on it.
  2. Check the supported bridge API surface (jsGet cases in JsJava.java) and use only those names.
  3. For collections, use Java.to(...) instead of Nashorn-era helpers.
  4. Fix capitalization/typos in the member name after Java.

Example fix

// before
var List = Java.import('java.util.ArrayList'); // no such api
// after
var ArrayList = Java.type('java.util.ArrayList');
var list = new ArrayList();
Defensive patterns

Strategy: validation

Validate before calling

// only Java.type / Java.to (and documented cases) are valid; check the member name against the JsJava bridge surface before use

Try / catch

try { var C = Java.type(name); } catch (e) { if (String(e).indexOf('no such api on Java') !== -1) { karate.log('use Java.type(...), not Java.' + name); } else { throw e; } }

Prevention

When it happens

Trigger: Writing Java.import('...') or Java.somethingElse(...) where the bridge only supports Java.type(...)/Java.to(...); typos like Java.Type(); porting Nashorn code that used APIs Karate's bridge does not provide.

Common situations: Migrating legacy Nashorn/GraalJS scripts that used Java.import or Java.extend; guessing at the bridge surface without checking documentation; case-sensitivity mistakes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

                // 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);
                }
                return type;
            };
            case "to" -> (JsInvokable) args -> {
                if (args[0] instanceof ExternalAccess ja) {
                    return ja.getJavaValue();
                }
                // TODO regex, functions, lambdas
                return null;
            };
            default -> throw JsErrorException.typeError("no such api on Java: " + name);
        };
    }

}

View on GitHub (pinned to a22eb90246)