{"record":{"id":"ad0ef34b626fac0e","repo":"xpipe-io/xpipe","slug":"unable-to-find-terminal-child-process-pid","errorCode":null,"errorMessage":"Unable to find terminal child process ${pid}","messagePattern":"Unable to find terminal child process (.+?)","errorType":"exception","errorClass":"BeaconClientException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/terminal/TerminalLauncherManager.java","lineNumber":83,"sourceCode":"    @SuppressWarnings(\"unused\")\n    public static boolean isCompletedSuccessfully(UUID request) {\n        synchronized (entries) {\n            var req = entries.get(request);\n            return req.getResult() instanceof TerminalLaunchResult.ResultSuccess;\n        }\n    }\n\n    public static void registerPid(UUID request, long pid) throws BeaconClientException {\n        TerminalLaunchRequest req;\n        synchronized (entries) {\n            req = entries.get(request);\n        }\n        if (req == null) {\n            return;\n        }\n        var byPid = ProcessHandle.of(pid);\n        if (byPid.isEmpty()) {\n            throw new BeaconClientException(\"Unable to find terminal child process \" + pid);\n        }\n        var shell = byPid.get().parent().orElseThrow();\n        if (req.getShellPid() != -1 && shell.pid() != req.getShellPid()) {\n            throw new BeaconClientException(\"Wrong launch context\");\n        }\n        req.setShellPid(shell.pid());\n    }\n\n    public static void waitExchange(UUID request) throws BeaconServerException {\n        TerminalLaunchRequest req;\n        synchronized (entries) {\n            req = entries.get(request);\n        }\n        if (req == null) {\n            return;\n        }\n\n        if (req.isSetupCompleted()) {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/terminal/TerminalLauncherManager.java#L65-L101","documentation":"TerminalLauncherManager.registerPid() links a spawned terminal child process (by PID) back to its launch request. If ProcessHandle.of(pid) finds no live process with that PID, it throws BeaconClientException(\"Unable to find terminal child process <pid>\"). This validates the reported child PID exists before binding its parent shell PID to the pending request.","triggerScenarios":"registerPid() called with a PID that is not a live process: child already exited and was reaped, PID reported by the terminal is wrong, or OS-level PID namespace differences (containers/SSH) make the PID invisible to this JVM.","commonSituations":"Terminal closed immediately after spawn so the process no longer exists; pidfile/env-reported PID stale by the time of registration; running inside a container where the child PID is not visible; platform differences in how the terminal reports its own PID.","solutions":["Retry the launch, keeping the terminal open so the child process is alive when the PID is registered","Verify the PID is reported correctly to registerPid (check env/argument passing of the pid)","Check PID namespace visibility (container/SSH) and register from within the same namespace","Log ProcessHandle.allProcesses() near failure time to confirm whether the child ever existed"],"exampleFix":"// before\nlong pid = readPidFile(); // stale pid\nTerminalLauncherManager.registerPid(pid); // throws\n// after\nProcessHandle.of(pid).ifPresentOrElse(\n    h -> TerminalLauncherManager.registerPid(pid),\n    () -> log.warn(\"pid \" + pid + \" already gone, relaunching\"));","handlingStrategy":"try-catch","validationCode":"if (ProcessHandle.of(pid).isEmpty()) {\n    // child already gone; relaunch instead of registering\n}\n","typeGuard":"Optional<ProcessHandle> handle = ProcessHandle.of(pid);\nif (handle.isPresent() && handle.get().isAlive()) { /* safe to register */ }","tryCatchPattern":"try {\n    TerminalLauncherManager.registerPid(pid);\n} catch (BeaconClientException e) {\n    if (e.getMessage().contains(\"Unable to find terminal child process\")) {\n        // child exited or PID invisible; relaunch the terminal\n    }\n}","preventionTips":["Keep the terminal open until registration completes","Pass the PID to the child reliably (env var/argument) and read it promptly","Be aware of PID namespaces in containers/SSH when validating PIDs","Check ProcessHandle.of(pid).isAlive() before calling registerPid"],"tags":["process","pid","terminal","beacon"],"backgroundTag":"resource-not-found","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}