github/copilot-sdk · error
; stderr
Error message
%w; stderr: %s
What it means
This is the augmented form of the start-wait timeout error: after the base error (context deadline/cancellation) is created, the library appends the CLI server's captured stderr via '%w; stderr: %s'. The stderr content is the actual diagnostic; the base error only tells you the wait timed out.
Solutions
- Read the 'stderr: ...' suffix first — it contains the CLI's own error (bad flag, missing auth, port in use).
- Fix the underlying CLI issue indicated in the stderr text.
- If stderr is only warnings, raise the context timeout so the server can finish starting.
- Run the CLI manually with the same arguments to reproduce and see full output.
Defensive patterns
Strategy: try-catch
Try / catch
if err := client.Start(ctx); err != nil {
if i := strings.Index(err.Error(), "stderr: "); i >= 0 {
log.Errorf("CLI stderr during failed start: %s", err.Error()[i+8:])
}
if errors.Is(err, context.DeadlineExceeded) { /* retry with longer ctx */ }
return err
} Prevention
- Always surface the stderr suffix in your logs/alerts.
- Fix the CLI-level error printed in stderr before adjusting timeouts.
- Run the CLI manually with the same args to reproduce startup failures.
- Validate CLI config/env before invoking the client.
When it happens
Trigger: Context cancellation while the CLI server is starting AND the process wrote anything to stderr (warnings, panics, flag errors) before being killed.
Common situations: CLI failing fast with a startup error message while the parent's timeout also fires; CLI emitting warnings on stderr that got captured before the kill.
Related errors
- CLI process exited unexpectedly
- CLI process exited unexpectedly. stderr
- CLI server process exited before reporting port
- failed waiting for CLI server to start
- timed out waiting for CLI process to exit after kill
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/78b514afd4ea0d9f.
Report an issue: GitHub.
Appendix: source
Thrown at go/client.go:2226
}
c.monitorProcess()
proc := c.process
scanner := bufio.NewScanner(stdout)
portRegex := regexp.MustCompile(`listening on port (\d+)`)
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
for {
select {
case <-ctx.Done():
killErr := c.killProcess()
baseErr := fmt.Errorf("failed waiting for CLI server to start: %w", ctx.Err())
if buf, ok := proc.Stderr.(*truncbuffer.TruncBuffer); ok {
if stderr := strings.TrimSpace(buf.String()); stderr != "" {
baseErr = fmt.Errorf("%w; stderr: %s", baseErr, stderr)
}
}
return errors.Join(baseErr, killErr)
case <-c.processDone:
killErr := c.killProcess()
baseErr := errors.New("CLI server process exited before reporting port")
if buf, ok := proc.Stderr.(*truncbuffer.TruncBuffer); ok {
if stderr := strings.TrimSpace(buf.String()); stderr != "" {
baseErr = fmt.Errorf("%w; stderr: %s", baseErr, stderr)
}
}
return errors.Join(baseErr, killErr)
default:
if scanner.Scan() {
line := scanner.Text()
if matches := portRegex.FindStringSubmatch(line); len(matches) > 1 {
port, err := strconv.Atoi(matches[1])
if err != nil {View on GitHub (pinned to cd8cf15dc3)