chenhg5/cc-connect · error

%s

Error message

%s

What it means

When the Copilot CLI process exits with a non-zero status and its stderr contains output, readLoop emits a core.EventError whose Error is the trimmed stderr text verbatim. This is not a fixed message: it surfaces whatever the CLI printed to stderr, so the developer sees the child process's actual failure output as an event on the session's event stream.

Source

Thrown at agent/copilot/session.go:258

	if _, err := rand.Read(b[:]); err != nil {
		return fmt.Sprintf("cc-connect-%d", time.Now().UnixNano())
	}
	b[6] = (b[6] & 0x0f) | 0x40
	b[8] = (b[8] & 0x3f) | 0x80
	return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])
}

func (cs *copilotSession) readLoop(stderrBuf *bytes.Buffer) {
	defer func() {
		cs.alive.Store(false)
		cs.rpc.cancelAll(fmt.Errorf("process exited"))

		// Wait for process exit
		if err := cs.cmd.Wait(); err != nil {
			stderrMsg := strings.TrimSpace(stderrBuf.String())
			if stderrMsg != "" {
				slog.Error("copilotSession: process failed", "error", err, "stderr", stderrMsg)
				evt := core.Event{Type: core.EventError, Error: fmt.Errorf("%s", stderrMsg)}
				select {
				case cs.events <- evt:
				case <-cs.ctx.Done():
				}
			}
		}
		close(cs.events)
		close(cs.done)
	}()

	for {
		body, err := cs.reader.readMessage()
		if err != nil {
			if cs.ctx.Err() != nil {
				return
			}
			slog.Error("copilotSession: read error", "error", err)
			return

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the event's message — it is the CLI's own stderr and usually states the exact problem (unknown flag, auth required, etc.).
  2. Re-authenticate the Copilot CLI if stderr mentions auth/token/401.
  3. Correct the command/args configured for the copilot agent in config.toml to match the installed CLI version.
  4. Run the CLI binary manually with the same args to reproduce and debug the failure outside cc-connect.
  5. Upgrade cc-connect and/or the CLI if the stderr shows protocol or flag incompatibility.

Example fix

// before: stderr event: "unknown flag: --foobar"
[[agents]]
name = "copilot"
args = ["--foobar"]
// after: use flags supported by the installed CLI
args = ["--model", "gpt-4o"]
Defensive patterns

Strategy: try-catch

Validate before calling

// capture CLI stderr early in a dry run
out, err := exec.Command(cliPath, args...).CombinedOutput()
if err != nil {
    return fmt.Errorf("copilot CLI fails with args %v: %v: %s", args, err, out)
}

Try / catch

for evt := range session.Events() {
    if evt.Type == core.EventError {
        // evt.Error text is the CLI's stderr — surface it to the user/log
        slog.Error("copilot CLI stderr", "stderr", evt.Error.Error())
    }
}

Prevention

When it happens

Trigger: readLoop -> cs.cmd.Wait() returns err != nil and stderrBuf is non-empty -> core.Event{Type: core.EventError, Error: fmt.Errorf("%s", stderrMsg)} is pushed to cs.events. Any CLI startup/runtime failure that writes to stderr triggers it (bad flag, auth failure, panic, missing binary).

Common situations: Wrong CLI path or args configured in config.toml so the CLI exits with usage errors; expired GitHub/Copilot auth; CLI panics on an unsupported request; host lacks a dependency the CLI needs (e.g. node runtime).

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/f4b6bb5e8100f677. Report an issue: GitHub.