{"record":{"id":"a57493f843bb4b84","repo":"github/copilot-sdk","slug":"interrupted-while-starting-in-process-runtime-host","errorCode":null,"errorMessage":"Interrupted while starting in-process runtime host.","messagePattern":"Interrupted while starting in-process runtime host\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/FfiRuntimeHost.java","lineNumber":253,"sourceCode":"                    synchronized (callbackDrainMonitor) {\n                        callbackDrainMonitor.notifyAll();\n                    }\n                }\n            }\n        };\n    }\n\n    private int runHostStartOnBlockingThread(byte[] argvJson, byte[] envJson) {\n        ReaderThreadFactory readerThreadFactory = new ReaderThreadFactory();\n        ExecutorService executor = Executors\n                .newSingleThreadExecutor(runnable -> readerThreadFactory.create(runnable, \"copilot-ffi-host-start\"));\n        try {\n            Future<Integer> future = executor.submit(() -> nativeBinding.hostStart(argvJson, argvJson.length, envJson,\n                    envJson == null ? 0 : envJson.length));\n            return future.get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IllegalStateException(\"Interrupted while starting in-process runtime host.\", e);\n        } catch (ExecutionException e) {\n            Throwable cause = e.getCause();\n            if (cause instanceof RuntimeException runtimeException) {\n                throw runtimeException;\n            }\n            throw new IllegalStateException(\"Failed to start in-process runtime host.\", cause);\n        } finally {\n            executor.shutdownNow();\n            try {\n                executor.awaitTermination(5, TimeUnit.SECONDS);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n        }\n    }\n\n    private static byte[] buildArgvJson(String entrypointPath, CopilotClientOptions options) {\n        List<String> argv = new ArrayList<>();","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/FfiRuntimeHost.java#L235-L271","documentation":"runHostStartOnBlockingThread submits the native hostStart call to a single-use executor and blocks on future.get(). If the calling thread is interrupted while waiting, the library restores the interrupt flag and throws IllegalStateException.","triggerScenarios":"Thread.interrupt() delivered to the thread blocked in start()/runHostStartOnBlockingThread — e.g. task cancellation, executor shutdown, or application shutdown interrupting worker threads.","commonSituations":"Cancelling a FutureTask/CompletableFuture wrapping client init; servlet container interrupting a slow request thread; test framework timeouts interrupting the test thread during slow native startup.","solutions":["Avoid interrupting threads performing FFI startup; use a dedicated startup thread not subject to cancellation.","Increase startup timeouts so watchdogs don't interrupt mid-start.","Retry initialization on a fresh (non-interrupted) thread with a new FfiRuntimeHost.","Catch IllegalStateException, check Thread.interrupted(), and handle shutdown gracefully."],"exampleFix":"// before\nexecutor.submit(() -> client.start(e, o)).cancel(true); // interrupts mid-FFI\n// after\ninitFuture = CompletableFuture.runAsync(() -> client.start(e, o), initExecutor);\n// don't cancel(true) during native start; await completion","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"if (Thread.currentThread().isInterrupted()) { /* defer init to a fresh thread */ }","tryCatchPattern":"try { host.start(e, o); } catch (IllegalStateException ex) { if (ex.getCause() instanceof InterruptedException || Thread.interrupted()) { /* reschedule init on new thread */ } else throw ex; }","preventionTips":["Run FFI startup on a dedicated thread not subject to cancel(true)","Size startup timeouts generously so watchdogs don't interrupt","Preserve and check interrupt status before retrying"],"tags":["java","ffi","interruption","concurrency"],"backgroundTag":"request-timeout","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}