karatelabs/karate · error · RuntimeException

at least one feature file is required

Error message

at least one feature file is required

What it means

MockServer.start() refuses to boot a mock server with zero registered features, since there would be nothing to serve. Karate throws this eagerly at startup instead of silently starting an empty server.

Solutions

  1. Call .feature(path) with a valid feature file path before start()
  2. If loading by package/glob, verify resources are on the classpath (check target/test-classes or the jar)
  3. Log features.size() before start() to confirm the builder collected the features
  4. Ensure you start the same builder instance you configured

Example fix

// before
MockServer server = MockServer.builder().http(8080).build().start();
// after
MockServer server = MockServer.builder()
        .feature("classpath:mocks/users-mock.feature")
        .http(8080).build().start();
Defensive patterns

Strategy: validation

Validate before calling

if (features == null || features.isEmpty()) throw new IllegalStateException("no features configured for MockServer");

Try / catch

try { server.start(); } catch (RuntimeException e) { if ("at least one feature file is required".equals(e.getMessage())) { log.error("MockServer built with zero features — check feature() calls and resource paths"); } throw e; }

Prevention

When it happens

Trigger: Calling MockServer.builder().start() without any .feature(...) call, or building features from a path/glob that resolved to nothing at build time.

Common situations: Wrong classpath path to the feature file; using a glob that matched no files; feature() calls accidentally removed or guarded by a condition; features added to a different builder instance than the one started.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/MockServer.java:330

        /**
         * Evaluate embedded {@code #(...)} expressions found in request-derived data
         * (request/requestHeaders/requestParams). OFF by default: attacker-controlled request
         * data is treated as inert data, not Karate code. Only enable for trusted mocks that
         * intentionally template off request content. Individual features can also opt in with
         * {@code configure requestExpressionsEnabled = true}.
         */
        public Builder requestExpressionsEnabled(boolean requestExpressionsEnabled) {
            this.requestExpressionsEnabled = requestExpressionsEnabled;
            return this;
        }

        /**
         * Start the mock server.
         */
        public MockServer start() {
            if (features.isEmpty()) {
                throw new RuntimeException("at least one feature file is required");
            }

            // Create handler - use ReloadingHandler wrapper if watch mode is enabled
            Function<HttpRequest, HttpResponse> requestHandler;
            MockHandler handler;

            if (watch) {
                ReloadingHandler reloadingHandler = new ReloadingHandler(features, args, pathPrefix, javaBridgeEnabled, requestExpressionsEnabled);
                handler = reloadingHandler.getHandler();
                requestHandler = reloadingHandler;
                logger.info("watch mode enabled - features will be reloaded when modified");
            } else {
                handler = new MockHandler(features, args, pathPrefix, javaBridgeEnabled, requestExpressionsEnabled);
                requestHandler = handler;
            }

            SslContext sslContext = null;
            if (ssl) {

View on GitHub (pinned to a22eb90246)