{"record":{"id":"bc9181762f896ff4","repo":"github/copilot-sdk","slug":"failed-waiting-for-cli-server-to-start-w","errorCode":null,"errorMessage":"failed waiting for CLI server to start: %w","messagePattern":"failed waiting for CLI server to start: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/client.go","lineNumber":2223,"sourceCode":"\n\t\tif err := c.process.Start(); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to start CLI server: %w\", err)\n\t\t}\n\n\t\tc.monitorProcess()\n\n\t\tproc := c.process\n\t\tscanner := bufio.NewScanner(stdout)\n\t\tportRegex := regexp.MustCompile(`listening on port (\\d+)`)\n\n\t\tctx, cancel := context.WithTimeout(ctx, 10*time.Second)\n\t\tdefer cancel()\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\tkillErr := c.killProcess()\n\t\t\t\tbaseErr := fmt.Errorf(\"failed waiting for CLI server to start: %w\", ctx.Err())\n\t\t\t\tif buf, ok := proc.Stderr.(*truncbuffer.TruncBuffer); ok {\n\t\t\t\t\tif stderr := strings.TrimSpace(buf.String()); stderr != \"\" {\n\t\t\t\t\t\tbaseErr = fmt.Errorf(\"%w; stderr: %s\", baseErr, stderr)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn errors.Join(baseErr, killErr)\n\t\t\tcase <-c.processDone:\n\t\t\t\tkillErr := c.killProcess()\n\t\t\t\tbaseErr := errors.New(\"CLI server process exited before reporting port\")\n\t\t\t\tif buf, ok := proc.Stderr.(*truncbuffer.TruncBuffer); ok {\n\t\t\t\t\tif stderr := strings.TrimSpace(buf.String()); stderr != \"\" {\n\t\t\t\t\t\tbaseErr = fmt.Errorf(\"%w; stderr: %s\", baseErr, stderr)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn errors.Join(baseErr, killErr)\n\t\t\tdefault:\n\t\t\t\tif scanner.Scan() {\n\t\t\t\t\tline := scanner.Text()","sourceCodeStart":2205,"sourceCodeEnd":2241,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/client.go#L2205-L2241","documentation":"The library waits for the spawned CLI server to print its port on stdout. If the caller's context is cancelled or times out before the port is reported, the process is killed and this error is returned, with the context's error (DeadlineExceeded or Canceled) embedded. Any captured stderr is appended to aid diagnosis.","triggerScenarios":"Passing a ctx that is cancelled or expires while the CLI server is still starting, e.g. a too-short context timeout around client.Start().","commonSituations":"Slow machine or cold-start of the CLI binary exceeding a tight deadline; HTTP request timeouts propagating their context into the start call; test suites with short timeouts.","solutions":["Increase the context timeout/deadline passed to the start call.","Inspect the appended 'stderr:' portion for the real startup failure (bad flag, port conflict, missing config).","Ensure no caller cancels the context prematurely (e.g. request handler scopes).","If the CLI is slow on first run due to download/auth, perform that warm-up outside the start context."],"exampleFix":"// before\nclient.Start(ctx) // ctx with 2s deadline\n// after\nstartCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\nclient.Start(startCtx)","handlingStrategy":"try-catch","validationCode":"if deadline, ok := ctx.Deadline(); ok {\n    if time.Until(deadline) < 30*time.Second {\n        return errors.New(\"context deadline too short for CLI server startup\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := client.Start(ctx); err != nil {\n    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {\n        // inspect embedded stderr; retry with a longer timeout\n    }\n    return err\n}","preventionTips":["Use a generous startup timeout (30-60s) independent of request deadlines.","Never pass request-scoped contexts into the start call.","Warm up the CLI (first-run downloads/auth) before the timed start.","Log the stderr suffix — it reveals the real startup delay cause."],"tags":["process","timeout","context","startup"],"backgroundTag":"process-start-timeout","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}