karatelabs/karate · error · JsErrorException

. is not a function (called on )

Error message

. is not a function (called on )

What it means

Thrown by JavaUtils.invokeStatic when a static method with the given name and compatible argument types cannot be found on the Java class. The JS engine surfaces it as a TypeError '.<name> is not a function (called on <TypeName>' so script authors see a familiar JS-style message for Java interop failures.

Solutions

  1. Verify the method exists as a static member of that exact class (check javadoc for your JDK/library version).
  2. Ensure arguments' types match an overload; wrap numbers with java.lang.Integer or java.lang.Long as needed.
  3. If it's an instance method, get an instance first and call it on that object.
  4. Use class.getMethods()-style inspection (or karate.log on the Java.type result) to list available methods.

Example fix

// before
var System = Java.type('java.lang.System');
var val = System.getenv('MY_VAR');
// after (method exists but must be called on env map for non-simple names)
var System = Java.type('java.lang.System');
var env = System.getenv();
var val = env.get('MY_VAR');
Defensive patterns

Strategy: type-guard

Validate before calling

var System = Java.type('java.lang.System');
if (!System.getenv) karate.fail('System.getenv not available in this interop context');

Type guard

function hasStatic(clazz, name) { try { var m = clazz.getClass().getMethod(name); return java.lang.reflect.Modifier.isStatic(m.getModifiers()); } catch (e) { return false; } }

Try / catch

try { return Clz.method(args); } catch (e) { if (String(e).indexOf('is not a function') !== -1) { karate.log('missing static method on', Clz); return null; } throw e; }

Prevention

When it happens

Trigger: Calling SomeClass.someStatic(...) from a Karate JS block where the class has no static method of that name, or where the arguments match no overload.

Common situations: Method renamed/moved across JDK or library versions; calling an instance method as if static; argument type mismatch (JS number vs int/long overload).

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JavaUtils.java:59

        if (clazz == Boolean.class || clazz == boolean.class) return "Boolean";
        if (clazz == Character.class || clazz == char.class) return "String";
        if (Set.class.isAssignableFrom(clazz)) return "Set";
        return clazz.getSimpleName();
    }

    static Object construct(Class<?> clazz, Object[] args) {
        try {
            Constructor<?> constructor = findConstructor(clazz, args);
            return constructor.newInstance(args);
        } catch (Exception e) {
            throw JsErrorException.typeError(jsTypeName(clazz) + " is not a constructor");
        }
    }

    static Object invokeStatic(Class<?> clazz, String name, Object[] args) {
        Method method = findMethod(clazz, name, args);
        if (method == null) {
            throw JsErrorException.typeError("." + name + " is not a function (called on " + jsTypeName(clazz) + ")");
        }
        try {
            return invoke(null, method, args);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException re) {
                throw re;
            }
            if (cause instanceof Error err) {
                throw err;
            }
            throw new RuntimeException(cause == null ? e.getMessage() : cause.getMessage(), cause);
        } catch (IllegalAccessException e) {
            throw JsErrorException.typeError("." + name + " is not accessible (on " + jsTypeName(clazz) + ")");
        }
    }

    static Object invoke(Object object, String name, Object[] args) {

View on GitHub (pinned to a22eb90246)