{"record":{"id":"b348436657cabfeb","repo":"quarkusio/quarkus","slug":"tests-already-in-progress","errorCode":null,"errorMessage":"Tests already in progress","messagePattern":"Tests already in progress","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java","lineNumber":66,"sourceCode":"                log.debug(\"Exception while aborting runner during reset\", e);\n            }\n            runner = null;\n        }\n    }\n\n    Runnable prepare(ClassScanResult classScanResult, boolean reRunFailures, long runId, TestRunListener listener) {\n        return prepare(classScanResult, reRunFailures, runId, listener, null);\n    }\n\n    Runnable prepare(ClassScanResult classScanResult, boolean reRunFailures, long runId, TestRunListener listener,\n            String specificSelection) {\n\n        var old = Thread.currentThread().getContextClassLoader();\n        Thread.currentThread().setContextClassLoader(testApplication.getOrCreateAugmentClassLoader());\n        try {\n            synchronized (this) {\n                if (runner != null) {\n                    throw new IllegalStateException(\"Tests already in progress\");\n                }\n                JunitTestRunner.Builder builder = new JunitTestRunner.Builder()\n                        .setClassScanResult(classScanResult)\n                        .setRunId(runId)\n                        .setTestState(testState)\n                        .setTestClassUsages(testClassUsages)\n                        .setTestApplication(testApplication)\n                        .setIncludeTags(testSupport.includeTags)\n                        .setExcludeTags(testSupport.excludeTags)\n                        .setInclude(testSupport.include)\n                        .setExclude(testSupport.exclude)\n                        .setSpecificSelection(specificSelection != null ? specificSelection : testSupport.specificSelection)\n                        .setIncludeEngines(testSupport.includeEngines)\n                        .setExcludeEngines(testSupport.excludeEngines)\n                        .setTestType(testSupport.testType)\n                        .setModuleInfo(moduleInfo)\n                        .addListener(listener)\n                        .setFailingTestsOnly(classScanResult != null && testSupport.brokenOnlyMode); //broken only mode is only when changes are made, not for forced runs","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java#L48-L84","documentation":"ModuleTestRunner.prepare throws IllegalStateException 'Tests already in progress' when a test run is requested while a previous runner instance is still active in the same synchronized block. Quarkus dev mode allows only one continuous-testing run at a time per module.","triggerScenarios":"Calling prepare() when the field 'runner' is non-null — i.e. a prior JUnit test run has not completed or was never marked finished, and another run (e.g. triggered by file change + test trigger) arrives concurrently.","commonSituations":"Continuous testing retriggered rapidly (save storms, all-files trigger) overlapping a slow previous run; paused/deadlocked test holding the runner; IDE and CLI both driving continuous testing.","solutions":["Wait for the current test run to finish before triggering another; avoid rapid re-saves","Stop and restart quarkus:dev if a previous run appears stuck","Ensure only one client (IDE or terminal) drives continuous testing","Report if reproducible — a run that never clears 'runner' indicates a lifecycle bug in the test runner"],"exampleFix":"// before: test paused at breakpoint, retriggers pile up\n// after: resume/stop the paused run, or disable continuous testing\nmvn quarkus:dev -Dquarkus.test.continuous-testing=disabled","handlingStrategy":"validation","validationCode":"if (runnerActive) {\n    throw new IllegalStateException(\"Skip trigger: a test run is already in progress\");\n} // or simply wait for the completed future before calling prepare again","typeGuard":"static boolean canStartRun(ModuleTestRunner r) {\n    synchronized (r) { return r.hasActiveRunner(); } // expose/track an active flag before prepare()\n}","tryCatchPattern":"try {\n    testRunner.prepare(ctx, runId);\n} catch (IllegalStateException e) {\n    if (\"Tests already in progress\".equals(e.getMessage())) {\n        // debounce: skip this trigger and let the current run finish\n        return;\n    }\n    throw e;\n}","preventionTips":["Debounce file-change triggers so one run completes before the next starts","Don't drive continuous testing from both IDE and CLI simultaneously","Unpause stuck breakpoints promptly; restart dev mode if a run never finishes"],"tags":["testing","continuous-testing","concurrency"],"backgroundTag":"operation-already-in-progress","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}