karatelabs/karate · error · RuntimeException
same-file tag call requires a feature context
Error message
same-file tag call requires a feature context
What it means
Identical in intent to the previous error but raised on the FeatureCall code path: when a `call` argument is a FeatureCall marked same-file with a tag selector, the executor derives the feature from the current feature runtime; if none exists (fr is null or has no Feature) it throws. A same-file tag call fundamentally requires a live feature to filter scenarios from.
Solutions
- Execute the call within a feature runtime that has an active Feature
- Replace the same-file tag call with an explicit path call: call classpath:path/to/file.feature@tag
- Avoid caching/reusing FeatureCall objects across contexts
- Verify the feature runtime (fr) is set before dynamic calls
Example fix
// before
* def fc = karate.readAndCall('@smoke') // same-file, no feature ctx
// after
* call classpath:examples/users.feature@smoke Defensive patterns
Strategy: validation
Try / catch
try { karate.call(fc) } catch (e) { if (String(e).indexOf('feature context') >= 0) karate.call('explicit.feature@tag') } Prevention
- Construct FeatureCall objects only where a feature runtime exists
- Use path-based calls for dynamic invocation
- Test dynamic call helpers inside a real feature run
When it happens
Trigger: A call step whose argument evaluates to a same-file FeatureCall (created with a tag selector) executed in a context with no current Feature; e.g. dynamic `call foo` where foo was built programmatically as a same-file call and run outside a feature.
Common situations: Constructing FeatureCall objects in JS/Java and invoking them from embedded scripts; runner setups that execute steps without an owning feature; refactors that moved a same-file tag call into a shared utility executed standalone.
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
- call with tag selector requires a feature context
- called feature failed
- expected Feature or FeatureCall, got:
- karate.call() is not available in this context
- mock background failed at line
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/cb529f13b660f895.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/StepExecutor.java:2762
/**
* Execute a feature call with a Feature or FeatureCall object.
* Used when the call expression evaluates to a Feature variable.
* Supports array loop calling when argExpr evaluates to a List.
*/
@SuppressWarnings("unchecked")
private void executeFeatureCall(Object featureObj, String argExpr, String resultVar) {
FeatureRuntime fr = runtime.getFeatureRuntime();
Feature calledFeature;
String tagSelector = null;
if (featureObj instanceof FeatureCall) {
FeatureCall fc = (FeatureCall) featureObj;
if (fc.isSameFile()) {
calledFeature = fr != null ? fr.getFeature() : null;
if (calledFeature == null) {
throw new RuntimeException("same-file tag call requires a feature context");
}
} else {
calledFeature = fc.getFeature();
}
tagSelector = fc.getTagSelector();
} else if (featureObj instanceof Feature) {
calledFeature = (Feature) featureObj;
} else {
throw new RuntimeException("expected Feature or FeatureCall, got: " + featureObj.getClass());
}
// Karate-expression eval handles inline JSON with embedded `#(...)`,
// arrays, variables, and bare JS uniformly.
Object argObj = argExpr == null ? null : evalKarateExpression(argExpr);
// Check if it's an array loop call
if (argObj instanceof List) {
List<Map<String, Object>> results = callFeatureLoop(calledFeature, (List<?>) argObj, tagSelector, null);View on GitHub (pinned to a22eb90246)