github/copilot-sdk · warning
failed to kill CLI process
Error message
failed to kill CLI process: %w
What it means
When stopping or force-stopping the client, the library kills the tracked CLI OS process. If os.Process.Kill() returns an error (process already finished with an OS error, permission problem, or handle issues), this error wraps it. It means cleanup of the child process did not complete cleanly.
Solutions
- Ignore 'process already finished' style errors — the process is gone, which is the goal; wrap Stop in a tolerated check.
- Avoid concurrent Stop calls; serialize with your own mutex or use the client's forceStop path only once.
- Check permissions in containers/restricted environments (signal rights, PID namespaces).
- If the process is stuck in D state, inspect the OS (dmesg) rather than retrying the kill.
Example fix
// before
if err := client.Stop(ctx); err != nil { return err }
// after
if err := client.Stop(ctx); err != nil {
if !strings.Contains(err.Error(), "process already finished") {
return err
}
} Defensive patterns
Strategy: fallback
Try / catch
if err := client.Stop(ctx); err != nil {
if strings.Contains(err.Error(), "process already finished") {
return nil // process is gone; stop goal achieved
}
return err
} Prevention
- Serialize Stop calls; never stop the same client concurrently.
- Treat 'already finished' kill errors as success.
- Check signal permissions in containers before relying on graceful kill.
- Monitor for stray CLI processes to detect repeated kill failures.
When it happens
Trigger: Calling client Stop/forceStop when the OS refuses the kill signal — e.g. the process already exited and was reaped unexpectedly, or the process runs as a different user.
Common situations: Double-stop from concurrent callers, killing a process owned by another user or in an uninterruptible state, container environments restricting signals.
Related errors
- timed out waiting for CLI process to exit after kill
- An in-process FFI runtime library is already loaded from
- An in-process FFI runtime library is already loaded from
- CLI process exited unexpectedly.
- CLI process exited unexpectedly
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/f871e2f752d9cfa4.
Report an issue: GitHub.
Appendix: source
Thrown at go/client.go:2364
environment["COPILOT_DISABLE_KEYTAR"] = "1"
}
return inProcessHostConfig{
Environment: environment,
Args: args,
}
}
func (c *Client) killProcess() error {
// Tear down the in-process FFI host on error paths that reuse killProcess to
// abort a start (there is no OS process to kill in that mode).
if c.ffiHost != nil {
c.ffiHost.Dispose()
c.ffiHost = nil
}
if p := c.osProcess.Swap(nil); p != nil {
if err := p.Kill(); err != nil {
return fmt.Errorf("failed to kill CLI process: %w", err)
}
}
c.process = nil
return nil
}
func (c *Client) killProcessAndWait() error {
done := c.processDone
killErr := c.killProcess()
if done == nil {
return killErr
}
select {
case <-done:
return killErr
case <-time.After(processExitTimeout):
return errors.Join(killErr, fmt.Errorf("timed out waiting for CLI process to exit after kill"))View on GitHub (pinned to cd8cf15dc3)