karatelabs/karate · error · IllegalArgumentException

logReplayLimit must be at least 1, was: (use…

Error message

logReplayLimit must be at least 1, was:  (use logReplay(FAILED) to replay only the failing feature)

What it means

KarateProtocolBuilder.logReplayLimit(int) caps how many log entries are replayed per request in the Gatling report. A value below 1 is rejected because zero would retain nothing while silently turning the ALL replay mode into FAILED-like behavior; the message also hints at using logReplay(FAILED) for the common intent.

Solutions

  1. Pass a positive integer, e.g. logReplayLimit(100)
  2. If the goal is 'only failing requests', call logReplay(FAILED) instead of limit 0
  3. If the goal is everything, keep the default / logReplay(ALL) and a large limit

Example fix

// before
protocol.logReplayLimit(Integer.getInteger("replay.limit", 0));
// after
protocol.logReplayLimit(Integer.getInteger("replay.limit", 100));
Defensive patterns

Strategy: validation

Validate before calling

if (limit < 1) { throw new IllegalArgumentException("logReplayLimit must be >= 1"); }

Try / catch

try {
  protocol.logReplayLimit(limit);
} catch (IllegalArgumentException e) {
  protocol.logReplayLimit(100);
}

Prevention

When it happens

Trigger: Calling logReplayLimit(0) or logReplayLimit(negative), usually from an integer parsed from config where the property was missing/mistyped (e.g. Integer.parseInt("") handled elsewhere, or default 0).

Common situations: Config placeholder defaulting to 0; developer wanting 'unlimited' and guessing 0 means unlimited; migrating from a boolean-style setting.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at karate-gatling/src/main/java/io/karatelabs/gatling/KarateProtocolBuilder.java:152

        }
        return this;
    }

    /**
     * How many already-passed feature logs to retain per virtual user in
     * {@link KarateLogReplay#ALL} mode, defaulting to {@value LogReplayer#DEFAULT_LIMIT}. This text
     * is held in memory for every virtual user until it is replayed or dropped, so raise it with
     * the run's concurrency in mind. Once a replay happens the retained logs are cleared, which is
     * what keeps the window to the current iteration in the common case — Gatling gives an action
     * no iteration boundary to hook, so the guarantee is "the last N Karate calls for this user".
     *
     * @return this builder for chaining
     */
    public KarateProtocolBuilder logReplayLimit(int limit) {
        if (limit < 1) {
            // zero would retain nothing AND report nothing dropped, quietly turning ALL into
            // FAILED — which is a mode you can just ask for
            throw new IllegalArgumentException("logReplayLimit must be at least 1, was: " + limit
                    + " (use logReplay(FAILED) to replay only the failing feature)");
        }
        this.logReplayLimit = limit;
        return this;
    }

    /**
     * Share one connection pool across the whole simulation, instead of opening a connection per
     * iteration.
     *
     * <p>Karate builds an HTTP client per scenario execution, so under Gatling it reconnects every
     * iteration where plain Gatling reuses a connection per virtual user. On a two-host bench that
     * was 4000 distinct client ports against 8, and collapsing it was worth about 24% of Karate's
     * per-iteration overhead against a plaintext endpoint on the same network — more against a
     * public TLS endpoint, where the avoided handshake costs two round trips and asymmetric crypto.
     *
     * <p><b>Read {@link PooledHttpClientFactory} before turning this on.</b> A pooled client cannot
     * honour {@code configure ssl} set inside a scenario and ignores it silently, and NTLM does not

View on GitHub (pinned to a22eb90246)