github/copilot-sdk · critical

failed to start CLI server

Error message

failed to start CLI server: %w

What it means

Connect wraps the error from process.Start() with this message when the CLI subprocess cannot be launched in stdio mode. The JSON-RPC session is never established. Typical causes are a missing/non-executable binary, bad working directory, or exec failures.

Solutions

  1. Verify the CLI binary path is correct and the binary exists and is executable (which <cli>, chmod +x).
  2. Install the required CLI (e.g. npm install -g @anthropic-ai/claude-code) or point the SDK at the right path.
  3. Check the wrapped error: 'no such file or directory' means bad path; 'permission denied' means missing exec bit.
  4. Ensure the working directory passed to the command exists and the binary matches the OS/architecture.

Example fix

// before
client, _ := NewClient(WithCommand("claude-x")) // typo, not installed
client.Connect(ctx) // failed to start CLI server: exec: "claude-x": executable file not found

// after
client, _ := NewClient(WithCommand("claude"))
if err := client.Connect(ctx); err != nil {
    return fmt.Errorf("connect: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

path := "claude" // or configured command
if _, err := exec.LookPath(path); err != nil {
    return fmt.Errorf("CLI binary %q not found in PATH: %w", path, err)
}

Try / catch

if err := client.Connect(ctx); err != nil {
    if strings.Contains(err.Error(), "failed to start CLI server") {
        return fmt.Errorf("check CLI install/path: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Connect() with useStdio enabled and os/exec Start() fails: CLI binary path not found, binary lacks execute permission, invalid working directory, or exec format error.

Common situations: CLI not installed or not on PATH, wrong WithCommand/args configuration, running on an unsupported platform/architecture, or restricted container images without the binary.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/f18f63b905c4d38a. Report an issue: GitHub.

Appendix: source

Thrown at go/client.go:2182

		}
	}

	if c.useStdio {
		// For stdio mode, we need stdin/stdout pipes
		stdin, err := c.process.StdinPipe()
		if err != nil {
			return fmt.Errorf("failed to create stdin pipe: %w", err)
		}

		stdout, err := c.process.StdoutPipe()
		if err != nil {
			return fmt.Errorf("failed to create stdout pipe: %w", err)
		}

		c.process.Stderr = truncbuffer.NewTruncBuffer(stderrBufferSize)

		if err := c.process.Start(); err != nil {
			return fmt.Errorf("failed to start CLI server: %w", err)
		}

		c.monitorProcess()

		// Create JSON-RPC client immediately
		c.client = jsonrpc2.NewClient(stdin, stdout)
		c.client.SetProcessDone(c.processDone, c.processErrorPtr)
		c.client.SetOnClose(c.handleConnectionClose)
		c.RPC = rpc.NewServerRPC(c.client)
		c.internalRPC = rpc.NewInternalServerRPC(c.client)
		c.setupNotificationHandler()
		c.client.Start()

		return nil
	} else {
		// For TCP mode, capture stdout to get port number
		stdout, err := c.process.StdoutPipe()
		if err != nil {

View on GitHub (pinned to cd8cf15dc3)