{"record":{"id":"134aebf9b4e645c3","repo":"github/copilot-sdk","slug":"timeout-waiting-for-cli-to-announce-port","errorCode":null,"errorMessage":"Timeout waiting for CLI to announce port","messagePattern":"Timeout waiting for CLI to announce port","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/CliServerManager.java","lineNumber":209,"sourceCode":"            Pattern portPattern = Pattern.compile(\"listening on port (\\\\d+)\", Pattern.CASE_INSENSITIVE);\n            long deadline = System.currentTimeMillis() + 30000;\n\n            while (System.currentTimeMillis() < deadline) {\n                String line = reader.readLine();\n                if (line == null) {\n                    awaitStderrReader();\n                    String stderr = getStderrOutput();\n                    throw new IOException(formatCliExitedMessage(\"CLI process exited unexpectedly.\", stderr));\n                }\n\n                Matcher matcher = portPattern.matcher(line);\n                if (matcher.find()) {\n                    return Integer.parseInt(matcher.group(1));\n                }\n            }\n\n            process.destroyForcibly();\n            throw new IOException(\"Timeout waiting for CLI to announce port\");\n        }\n    }\n\n    String getStderrOutput() {\n        synchronized (stderrBuffer) {\n            return stderrBuffer.toString().trim();\n        }\n    }\n\n    private void awaitStderrReader() {\n        Thread t = this.stderrThread;\n        if (t != null) {\n            try {\n                t.join(STDERR_READER_JOIN_TIMEOUT_MS);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n            }\n        }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/CliServerManager.java#L191-L227","documentation":"waitForPortAnnouncement waits until a deadline for the CLI to print its TCP port on stdout. If the deadline expires without a port announcement, the manager forcibly destroys the process and throws IOException. The CLI either never announces a port or takes longer than the timeout.","triggerScenarios":"startCliServer's stdout reader loops until the deadline while no line matches the port pattern — slow CLI startup (cold cache, slow machine), a CLI version that doesn't print the port, or startup blocked waiting for input/auth.","commonSituations":"Very slow CI machines exceeding the startup timeout; CLI hanging on an interactive prompt; version mismatch where the CLI output format no longer matches the expected port pattern; network/auth stalls during CLI boot.","solutions":["Increase the CLI startup timeout if startup is merely slow on your machine/CI.","Run the CLI manually to confirm it starts and announces a port in the expected format.","Update the SDK and CLI together so the port-announcement format matches.","Inspect stderr output captured by the manager for hints about what the CLI is waiting on."],"exampleFix":"// before\nCopilotClient client = new CopilotClient(options); // default short timeout\n// after\noptions.setTimeout(Duration.ofSeconds(120)); // allow slow CLI startup\nCopilotClient client = new CopilotClient(options);","handlingStrategy":"retry","validationCode":"long started = System.currentTimeMillis();\n// ensure your configured startup timeout exceeds worst-case CLI boot time on target machines","typeGuard":null,"tryCatchPattern":"try {\n  client = manager.startCliServer();\n} catch (IOException e) {\n  if (e.getMessage().contains(\"Timeout waiting for CLI\")) {\n    // retry once, or increase startup timeout\n  } else throw e;\n}","preventionTips":["Configure a generous startup timeout, especially on slow CI runners.","Run the CLI manually once to confirm it announces its port in the expected format.","Check for interactive prompts/auth stalls during CLI startup.","Keep CLI and SDK versions aligned so output format matches the parser."],"tags":["java","cli","timeout","startup"],"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"}