karatelabs/karate · error · RuntimeException
call with tag selector requires a feature context
Error message
call with tag selector requires a feature context
What it means
A 'call' step using a tag selector (e.g. 'call read("@tagName")') resolves against the current feature; when the step executor has no enclosing FeatureRuntime/Feature in context, Karate throws this RuntimeException because tag-based same-file calls have nothing to search.
Solutions
- Ensure the call is executed within a loaded feature (a proper FeatureRuntime / runner context)
- Replace the '@tag' selector with an explicit path to the feature or Scenario: 'call read("path/to/feature.feature")'
- If calling code directly, construct a Feature for the current resource so getFeature() is non-null
Example fix
// before: tag selector with no feature context
call read('@setup-data')
// after: call the feature explicitly or ensure runner context
call read('classpath:helpers/setup.feature') Defensive patterns
Strategy: try-catch
Validate before calling
// guard before tag-selector calls: need a feature context
if (callExpr.startsWith("@") && featureRuntime == null) {
throw new IllegalStateException("@tag call requires a loaded feature context");
} Try / catch
try { result = karate.call(expr, arg); } catch (RuntimeException e) { if (e.getMessage().contains("requires a feature context")) { throw new IllegalStateException("use explicit feature path instead of @tag selector"); } throw e; } Prevention
- Use @tag selectors only inside features run by the Karate runner
- Prefer explicit feature paths in programmatic calls
- Initialize FeatureRuntime before invoking the step engine directly
When it happens
Trigger: Invoking evalCallExpression / executeCallWithResult with call.sameFile=true (a '@tag' selector) while fr is null or fr.getFeature() is null — e.g. calling a tag-scoped section from outside a loaded feature, or embedding the step executor in a non-feature harness.
Common situations: Programmatic/driver use of Karate's step engine without a FeatureRuntime; running a snippet harness that calls tag sections; tests invoking karate.call() with a '@tag' path before any feature is loaded.
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
- called feature failed
- same-file tag call requires a feature context
- expected Feature or FeatureCall, got:
- input must not be null
- input string must not be empty or blank
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/f0d73f553fd7f17e.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/StepExecutor.java:440
} else if (evaluated instanceof FeatureCall || evaluated instanceof Feature) {
executeFeatureCall(evaluated, parts.arg(), resultVar);
return;
}
}
// Standard feature call
CallExpression call = parseCallExpression(callExpr);
call.resultVar = resultVar;
// Resolve the feature file relative to current feature
FeatureRuntime fr = runtime.getFeatureRuntime();
Feature calledFeature;
if (call.sameFile) {
// Same-file tag call - use current feature
calledFeature = fr != null ? fr.getFeature() : null;
if (calledFeature == null) {
throw new RuntimeException("call with tag selector requires a feature context");
}
} else {
Resource calledResource = fr != null
? fr.resolve(call.path)
: Resource.path(call.path);
calledFeature = Feature.read(calledResource);
}
// Check if it's an array loop call
if (call.argList != null) {
runtime.setVariable(resultVar, callFeatureLoop(calledFeature, call.argList, call.tagSelector, call.lineFilters));
return;
}
// Single call
Map<String, Object> resultVars = callFeatureSingle(calledFeature, call.arg, call.tagSelector, call.lineFilters);
if (resultVars != null) {
runtime.setVariable(resultVar, resultVars);View on GitHub (pinned to a22eb90246)