{"record":{"id":"1715ddc2009ab5bb","repo":"karatelabs/karate","slug":"karate-setup-requires-a-feature-context","errorCode":null,"errorMessage":"karate.setup() requires a feature context","messagePattern":"karate\\.setup\\(\\) requires a feature context","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java","lineNumber":513,"sourceCode":"                }\n                logger.debug(\"Evaluated {}: {} variables\", displayName, vars.size());\n                return vars;\n            } else if (result != null) {\n                logger.warn(\"{} did not return an object, got: {}\", displayName, result.getClass().getSimpleName());\n            }\n            return null;\n        } catch (Exception e) {\n            logger.warn(\"Failed to evaluate {}: {}\", displayName, e.getMessage());\n            throw new RuntimeException(\"Config evaluation failed: \" + displayName + \" - \" + e.getMessage(), e);\n        }\n    }\n\n    /**\n     * Execute the @setup scenario and return all its variables.\n     */\n    public Map<String, Object> executeSetup(String name) {\n        if (featureRuntime == null) {\n            throw new RuntimeException(\"karate.setup() requires a feature context\");\n        }\n        Scenario setupScenario = scenario.getFeature().getSetup(name);\n        if (setupScenario == null) {\n            String message = \"no scenario found with @setup tag\";\n            if (name != null) {\n                message = message + \" and name '\" + name + \"'\";\n            }\n            throw new RuntimeException(message);\n        }\n        // Run the setup scenario without background\n        ScenarioRuntime sr = new ScenarioRuntime(featureRuntime, setupScenario);\n        sr.setSkipBackground(true);\n        sr.call();\n        // The setup runtime re-evaluates config, and a failure there is now captured rather than\n        // thrown from the constructor. call()'s failed result is discarded here, so without this the\n        // caller gets an empty variable map and the config error resurfaces as a baffling\n        // \"x is not defined\" wherever a setup variable was expected. Fail where the cause is.\n        Throwable setupConfigError = sr.getConfigError();","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java#L495-L531","documentation":"executeSetup runs the @setup-tagged scenario of the current feature (karate.setup()). It requires a FeatureRuntime context — the enclosing feature being executed by the Karate runner. When ScenarioCaller/JS code calls karate.setup() outside a feature execution (featureRuntime is null), this RuntimeException is thrown.","triggerScenarios":"Calling karate.setup() (optionally with a name) from JS code that is not running inside a feature's scenario — e.g. from callSingle() cached code, a standalone JS script, or a config script evaluated before the feature runtime is attached.","commonSituations":"Using karate.setup() inside karate.callSingle() cached JS, which runs at suite level with no feature context; invoking setup helpers from karate-config.js; refactored JS moved from a Scenario into shared JS executed out of context.","solutions":["Call karate.setup() only from within a running feature's scenario or JS executed there.","If the code is shared via karate.callSingle(), refactor to not use setup (return data directly from the JS function).","If you control the caller, ensure featureRuntime is attached by running through a feature (Runner.path(...)) rather than ad-hoc JS evaluation.","Check for accidental API confusion: karate.call() / karate.setupOnce() have similar context requirements — verify you meant setup()."],"exampleFix":"// before: karate-config.js or callSingle JS\nvar data = karate.setup('makeData');\n\n// after: call setup inside a scenario / feature-scoped JS\nScenario:\n  * def data = karate.setup('makeData')","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function canSetup() {\n  // setup needs a feature context; only call it from scenario-scoped JS\n  return typeof karate.setup === 'function' && karate.runtime != null;\n}\n// usage inside a scenario:\n// if (canSetup()) karate.setup('makeData');","tryCatchPattern":"try {\n    var data = karate.setup('makeData');\n} catch (e) {\n    if (String(e).indexOf('requires a feature context') >= 0) {\n        karate.log('setup called outside feature scope; using defaults');\n        data = defaultData;\n    } else { throw e; }\n}","preventionTips":["Never call karate.setup() from karate-config.js or callSingle JS","Use setup only in scenario/Background scope of a running feature","Launch features via Runner.path(...) so FeatureRuntime exists","Do not move scenario-scoped JS helpers into suite-level utilities without auditing karate.* usage"],"tags":["setup","karate-js","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}