karatelabs/karate · warning · RuntimeException

listen interrupted

Error message

listen interrupted

What it means

While waiting for a listen result, the waiting thread was interrupted. The runtime restores the interrupt flag and throws "listen interrupted" wrapping the InterruptedException, aborting the listen step.

Solutions

  1. Ensure the external callback fires before test timeouts so listen completes normally
  2. Remove or extend enclosing test timeouts that cut off the scenario thread during listen
  3. On this error, treat it as a run-shutdown symptom: check for cancelled CI jobs or executor shutdown logs and re-run

Example fix

// before
@Timeout(5) @Test void oauthFlow() { /* contains * listen 60000 */ }
// after
@Timeout(120) @Test void oauthFlow() { /* listen can finish */ }
Defensive patterns

Strategy: try-catch

Try / catch

try { karate.listen(60000, 'token'); } catch (RuntimeException e) { if (e.getMessage().equals("listen interrupted")) { logger.warn("scenario interrupted during listen (shutdown or test timeout)"); } throw e; }

Prevention

When it happens

Trigger: The scenario thread waiting on listenLatch.await() is interrupted: test-run shutdown, JUnit/TestNG timeout or executor cancellation, karate.abort(), or JVM teardown while a listen is pending.

Common situations: CI job killed/cancelled mid-scenario; time-limited test runners (e.g. JUnit @Timeout) firing while a browser callback listen is pending; stepping/debugger stopping threads; parallel runner shutdown.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java:2485

    }

    /**
     * Wait for a signal with timeout.
     * Returns the signaled result or throws on timeout.
     */
    public Object waitForListenResult(long timeoutMs) {
        try {
            if (listenLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
                Object result = listenResult;
                // Reset for potential reuse
                listenResult = null;
                listenLatch = new CountDownLatch(1);
                return result;
            }
            throw new RuntimeException("listen timed out after " + timeoutMs + "ms");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("listen interrupted", e);
        }
    }

    /**
     * Get the current listen result without waiting.
     */
    public Object getListenResult() {
        return listenResult;
    }

    // ========== Performance Testing (Gatling Integration) ==========

    /**
     * Check if performance mode is enabled.
     * When true, HTTP request timing is reported via PerfHook.
     */
    public boolean isPerfMode() {
        return featureRuntime != null

View on GitHub (pinned to a22eb90246)