karatelabs/karate · error · RuntimeException

call expression must resolve to a feature path:

Error message

call expression must resolve to a feature path: 

What it means

For `call <text>` where the text is not a read() call, the executor evaluates it as a Karate expression expecting a String feature path (optionally with @tags). If the expression evaluates to a non-String (map, list, null-wrapped object, etc.), no feature path can be parsed and this error is thrown with the original expression text.

Solutions

  1. Make the expression return a string path: `def path = 'classpath:com/feat.feature'` then `call path`
  2. Use `call read('...')` for direct file references
  3. If calling a JS function, ensure the keyword/syntax used supports it (or wrap as call read of a feature that calls it)
  4. print the evaluated expression result to confirm its type

Example fix

// before
* def info = { path: 'users.feature' }
* call info
// after
* call info.path
# or ensure: * def info = 'users.feature'
Defensive patterns

Strategy: type-guard

Validate before calling

* if (typeof pathVar != 'string') karate.fail('call expression must be a string path')

Type guard

function isString(v) { return typeof v === 'string'; }

Prevention

When it happens

Trigger: `call someVar` where someVar holds a JSON/map/list; `call #(expr)` whose expression returns a non-string; JS function expressions used after `call` that return objects instead of a feature path string.

Common situations: Shadowing a feature-path variable with data earlier in the scenario; misunderstanding that `call` of a JS function requires different syntax in this engine; migration from Karate versions where call accepted function objects.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/9138701c8a536be3. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/StepExecutor.java:2939

                // (the V1 path — see evalKarateExpression). Variables and JS exprs
                // also resolve here; embedded-expression walking is built in.
                Object argObj = evalKarateExpression(text.substring(closeParen + 1).trim());
                if (argObj instanceof List) {
                    expr.argList = (List<?>) argObj;
                } else if (argObj instanceof Map) {
                    @SuppressWarnings("unchecked")
                    Map<String, Object> argMap = (Map<String, Object>) argObj;
                    expr.arg = argMap;
                }
            }
        } else {
            // Not a read() call - try evaluating as expression
            // Could be a variable that holds a feature path
            Object result = runtime.eval(text);
            if (result instanceof String) {
                parsePathAndTag((String) result, expr);
            } else {
                throw new RuntimeException("call expression must resolve to a feature path: " + text);
            }
        }

        return expr;
    }

    /**
     * Parse path and tag/line selector from a feature path.
     * Supports:
     * - file.feature@tag - call specific scenario by tag
     * - file.feature:N (or file.feature:N:M) - call by line number(s)
     * - @tag - call scenario in same file by tag
     */
    private void parsePathAndTag(String rawPath, CallExpression expr) {
        StepUtils.ParsedFeaturePath parsed = StepUtils.parseFeaturePath(rawPath);
        expr.path = parsed.path();
        expr.tagSelector = parsed.tagSelector();
        expr.sameFile = parsed.sameFile();

View on GitHub (pinned to a22eb90246)