karatelabs/karate · error · RuntimeException

karate.callonce() is not available in this context

Error message

karate.callonce() is not available in this context

What it means

karate.callonce() caches the result of a feature call per feature, but it needs a live ScenarioRuntime to store the cache and execute the call. Karate throws this when callonce is invoked from a JS context with no bound runtime (getRuntime() returns null).

Solutions

  1. Invoke karate.callonce() only from within a running scenario step so a ScenarioRuntime is bound.
  2. For suite-wide caching outside scenarios, use karate.callSingle() from a scenario, or the Runner/Suite-level APIs.
  3. Ensure custom JS invocation code binds the current ScenarioRuntime before evaluating the script.
  4. Check you are not accidentally calling callonce in a context where the runtime was cleared (e.g. after scenario teardown).

Example fix

// before: standalone JS with no runtime
var data = karate.callonce('classpath:shared.feature');

// after: inside a scenario step
// * def data = karate.callonce('classpath:shared.feature')
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof rt !== 'undefined' && rt != null) { karate.callonce('classpath:shared.feature'); }

Type guard

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

Try / catch

try { return karate.callonce(path, arg); } catch (e) { if (String(e.message).includes('not available in this context')) { throw new Error('callonce must run inside a scenario: ' + path); } throw e; }

Prevention

When it happens

Trigger: Invoking `karate.callonce('classpath:...')` from JS evaluated outside a scenario: an init script, a non-scenario thread, or a custom embedded JS engine where no ScenarioRuntime is attached.

Common situations: Running shared JS bootstrap code outside a feature; migrating callonce from older Karate versions into a new execution path; calling karate JS helpers from Java-embedded Nashorn/Graal contexts.

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/e81b6af81d721a50. Report an issue: GitHub.

Appendix: source

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

    JavaInvokable setupOnce() {
        return args -> {
            ScenarioRuntime rt = getRuntime();
            if (rt == null) {
                throw new RuntimeException("karate.setupOnce() is not available in this context");
            }
            String name = args.length > 0 && args[0] != null ? args[0].toString() : null;
            return rt.executeSetupOnce(name);
        };
    }

    /**
     * karate.callonce() - Execute a feature file once per feature and cache the result.
     */
    JavaInvokable callonce() {
        return args -> {
            ScenarioRuntime rt = getRuntime();
            if (rt == null) {
                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");

View on GitHub (pinned to a22eb90246)