karatelabs/karate · error · RuntimeException

karate.callSingle() is not available in this context

Error message

karate.callSingle() is not available in this context

What it means

karate.callSingle() runs a feature/JS file once per Suite and caches the result, which requires a ScenarioRuntime to execute and register the cache. Karate throws this when callSingle is used from a JS context where no runtime is bound (getRuntime() returns null).

Solutions

  1. Call karate.callSingle() from within a running scenario step so a ScenarioRuntime exists.
  2. For true suite-level pre-initialization, use Suite/Runner-level lifecycle hooks instead of JS karate.callSingle().
  3. When embedding the JS engine in Java, bind the current ScenarioRuntime before evaluating scripts that use callSingle.
  4. If called after scenario completion, move the call earlier in the scenario flow.

Example fix

// before: JS evaluated with no scenario bound
var token = karate.callSingle('classpath:auth.feature');

// after: inside a scenario
// * def token = karate.callSingle('classpath:auth.feature')
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof rt !== 'undefined' && rt != null) { var v = karate.callSingle('classpath:utils.js'); }

Type guard

function canCallSingle() { try { return typeof karate.callSingle === 'function' && !!getRuntime(); } catch (e) { return false; } }

Try / catch

try { return karate.callSingle(path); } catch (e) { if (String(e.message).includes('not available in this context')) { /* move call into a scenario or Suite hook */ } throw e; }

Prevention

When it happens

Trigger: Calling `karate.callSingle('classpath:...')` from JS evaluated outside any scenario: init scripts, worker/bootstrap threads, or custom embedded JS engines without a ScenarioRuntime.

Common situations: Trying to pre-load shared fixtures before the suite runs; calling callSingle from a Java harness embedding the karate JS object; invoking it from teardown/after hooks where the runtime is gone.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJsBase.java:405

                throw new RuntimeException("karate.callonce() is not available in this context");
            }
            if (args.length == 0) {
                throw new RuntimeException("karate.callonce() requires at least one argument (feature path)");
            }
            String path = args[0].toString();
            Object arg = args.length > 1 ? args[1] : null;
            return rt.executeJsCallOnce(path, arg);
        };
    }

    /**
     * karate.callSingle() - Execute a feature/JS file once per Suite and cache the result.
     */
    JavaInvokable callSingle() {
        return args -> {
            ScenarioRuntime rt = getRuntime();
            if (rt == null) {
                throw new RuntimeException("karate.callSingle() is not available in this context");
            }
            if (args.length == 0) {
                throw new RuntimeException("karate.callSingle() requires at least one argument (path)");
            }
            String path = args[0].toString();
            Object arg = args.length > 1 ? args[1] : null;
            return rt.executeCallSingle(path, arg);
        };
    }

    /**
     * karate.configure() - Apply configuration from JavaScript.
     */
    JavaInvokable configure() {
        return args -> {
            if (args.length < 2) {
                throw new RuntimeException("configure() needs two arguments: key and value");
            }

View on GitHub (pinned to a22eb90246)