karatelabs/karate · error · RuntimeException

karate.setupOnce() is not available in this context

Error message

karate.setupOnce() is not available in this context

What it means

karate.setupOnce() registers a setup routine that runs once per feature, but it requires an active ScenarioRuntime. Karate throws this when the JS `karate` object is accessed from a context where no scenario is executing (e.g. a standalone JS engine, a background/bootstrap hook, or a non-scenario thread), because there is no runtime to attach the setup-once callback to.

Solutions

  1. Call karate.setupOnce() only from JS evaluated inside a running scenario/feature so getRuntime() is non-null.
  2. If you need suite-level one-time setup outside a scenario, use the Suite/Runner level setup hooks (e.g. @BeforeSuite-style or Runner builder callbacks) instead of karate.setupOnce().
  3. Verify the JS execution path binds a ScenarioRuntime (call within a Scenario step or configure via the runtime-bound karate instance).
  4. Use karate.callSingle() at scenario level if the goal is once-per-suite caching rather than per-feature setup.

Example fix

// before: in an init script with no scenario
karate.setupOnce('setupUtils');

// after: called from within a scenario, or use Runner-level setup
// Scenario: init
// * karate.setupOnce('setupUtils')
Defensive patterns

Strategy: try-catch

Validate before calling

if (karate.setupOnce && typeof scenarioBound !== 'undefined' && scenarioBound) { karate.setupOnce('setupUtils'); }

Type guard

function canUseScenarioApi(karateObj) { try { return karateObj != null && typeof karateObj.setupOnce === 'function' && !!getRuntime(); } catch (e) { return false; } }

Try / catch

try { karate.setupOnce('setupUtils'); } catch (e) { if (String(e.message).includes('not available in this context')) { /* fall back to Runner-level setup hook */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling `karate.setupOnce(...)` from JS evaluated outside a running scenario: before the suite starts, from a hook that lacks a ScenarioRuntime, from a custom Java embedding point, or from a JS file invoked without a scenario context (getRuntime() returns null).

Common situations: Moving setup code out of a scenario into an init script; wiring karate JS APIs into a custom runner or embedded JS engine; calling setupOnce from a `Background`-adjacent or parallel-thread context where the runtime has not been bound yet.

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

Appendix: source

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

        };
    }

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

    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)");
            }

View on GitHub (pinned to a22eb90246)