{"record":{"id":"dafe817511b1d439","repo":"karatelabs/karate","slug":"registered-while-stopping-immediately","errorCode":null,"errorMessage":"registered while {}, stopping immediately: {}","messagePattern":"registered while (.+?), stopping immediately: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-js/src/main/java/io/karatelabs/common/KarateLifecycle.java","lineNumber":178,"sourceCode":"        }\n        Phase current;\n        long budgetNanos;\n        synchronized (LOCK) {\n            current = phase;\n            if (current == Phase.RUNNING) {\n                synchronized (REGISTERED) {\n                    if (indexOf(stoppable) < 0) {\n                        REGISTERED.add(stoppable);\n                    }\n                }\n                return;\n            }\n            budgetNanos = current == Phase.SHUTTING_DOWN\n                    ? Math.max(deadlineNanos - System.nanoTime(), 0)\n                    : DEFAULT_TIMEOUT.toNanos();\n        }\n        // outside the lock: stopping can block, and the drain needs the lock to record results\n        logger.warn(\"registered while {}, stopping immediately: {}\", current, name(stoppable));\n        stopBounded(stoppable, budgetNanos);\n    }\n\n    /**\n     * Remove a component from the register — call from the component's own stop path, so that\n     * something which stopped by itself (peer closed the socket, process exited) drops off too.\n     * Removing something not registered is a no-op, and null is ignored.\n     */\n    public static void unregister(Stoppable stoppable) {\n        if (stoppable == null) {\n            return;\n        }\n        synchronized (REGISTERED) {\n            int index = indexOf(stoppable);\n            if (index >= 0) {\n                REGISTERED.remove(index);\n            }\n        }","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/common/KarateLifecycle.java#L160-L196","documentation":"`KarateLifecycle.register` normally buffers stoppables for shutdown, but if registration happens while the lifecycle is already stopping or shut down, the component is stopped immediately with the remaining budget and this warning is logged. This prevents registering a resource that would otherwise never be stopped.","triggerScenarios":"A server/client/connection is created (and registers itself) concurrently with, or after, `shutdownAll()` — e.g. a late `karate.start()` during teardown, async task creating a stoppable while tests are shutting down; re-registration after a prior shutdown.","commonSituations":"Race between test teardown and background/async resource creation; shutdown triggered by a timeout or failure while a scenario still starts new resources; double shutdown in nested suites.","solutions":["Ensure all resource creation completes before shutdown begins (join async tasks first)","Do not start new stoppable resources during teardown; guard creation with a lifecycle check","If intentional, accept the warning — the component was still stopped with the remaining budget","Serialize setup/teardown to avoid concurrent shutdown and registration"],"exampleFix":"// before\nexecutor.submit(() -> startServerAndRegister()); // may run during shutdownAll()\n// after\nexecutor.submit(() -> startServerAndRegister()).get(); // complete before teardown begins","handlingStrategy":"type-guard","validationCode":"if (lifecycle.isShuttingDown()) throw new IllegalStateException(\"refusing to register \" + name + \" during shutdown\");","typeGuard":"boolean safeToRegister = lifecycle.phase() != Phase.SHUTTING_DOWN && lifecycle.phase() != Phase.SHUT_DOWN;","tryCatchPattern":null,"preventionTips":["Complete all resource creation before triggering shutdown","Join async setup tasks before teardown starts","Guard start calls with a lifecycle phase check"],"tags":["lifecycle","shutdown","concurrency","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}