chenhg5/cc-connect · critical
piSession: write get_state probe: %w
Error message
piSession: write get_state probe: %w
What it means
agent/pi/session.go:234 — after spawning the RPC child, startRPC writes a `{"type":"get_state"}` probe to the child's stdin to fetch the session id. If that write fails (usually because the pipe is broken because the child died or closed stdin immediately), the session is unrecoverable (no session id means /stop cannot resume), so startRPC kills the child and returns "piSession: write get_state probe: %w".
Source
Thrown at agent/pi/session.go:234
// Pi's RPC protocol does not push a "session" event on stdout — the only
// way to learn the session id is to send {"type":"get_state"} and parse
// the matching response in handleEvent. We probe immediately after spawn
// so that newPiSession's wait on rpcReady only unblocks once the id has
// been stored. readLoopRPC closes rpcReady as soon as sessionIDReady()
// flips to true (which happens after handleEvent processes the response),
// so callers can safely read CurrentSessionID() the moment rpcReady fires.
//
// If the probe write fails, the session is unrecoverable: without the
// session id we cannot resume after /stop, which is the very bug we are
// fixing. Bail out immediately and let the caller surface the error
// instead of waiting for the 30s rpcReady timeout.
if err := s.writeRPCCommand(map[string]any{
"type": "get_state",
"id": stateProbeID,
}); err != nil {
slog.Warn("piSession: failed to write get_state probe; aborting RPC start", "error", err)
s.killRPC()
return fmt.Errorf("piSession: write get_state probe: %w", err)
}
return nil
}
func (s *piSession) killRPC() {
if s.rpcCmd != nil && s.rpcCmd.Process != nil {
if err := forceKillCmd(s.rpcCmd); err != nil {
slog.Warn("piSession: kill rpc process", "error", err)
}
_, _ = s.rpcCmd.Process.Wait()
}
}
// readLoopRPC is the persistent RPC readLoop goroutine.
// One instance runs for the lifetime of the RPC process.
func (s *piSession) readLoopRPC(stdout io.ReadCloser) {
defer s.wg.Done()View on GitHub (pinned to 4000b2338a)
Solutions
- Run `pi --mode rpc` manually with the same extra args and check its stderr for the immediate-exit cause; fix flags/values in config.
- Upgrade the pi CLI to a version that supports `--mode rpc`.
- Check that required pi credentials/env (e.g. provider API keys) are set in the daemon environment or extraEnv.
- Retry session creation; if persistent, capture pi's stderr in daemon logs (slog.Warn already logs the probe error) for the underlying cause.
Example fix
// before extraArgs = ["--model", "gpt-nonexistent"] // pi exits instantly // after extraArgs = ["--model", "claude-sonnet-4"]
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify rpc support before starting a session:
out, err := exec.Command(piCmd, "--mode", "rpc", "--help").CombinedOutput()
if err != nil || !strings.Contains(string(out), "rpc") {
return fmt.Errorf("pi CLI lacks rpc mode support; upgrade pi")
} Try / catch
sess, err := agent.StartSession(ctx, sessionID, workDir)
if err != nil {
if strings.Contains(err.Error(), "write get_state probe") {
slog.Error("pi RPC process died at startup; check pi stderr", "err", err)
}
return err // session is unrecoverable; surface to user
} Prevention
- Keep the pi CLI up to date (rpc mode requires a recent version).
- Validate --model/--thinking/extraArgs values in config before deploying.
- Ensure provider credentials are present in the daemon environment.
- Test `pi --mode rpc` manually after any pi upgrade or config change.
When it happens
Trigger: Called from newPiSession in rpc mode when: (1) the pi process exits/crashes between cmd.Start() and the probe write; (2) pi rejects --mode rpc (older pi version without rpc support) and exits; (3) pi exits due to a bad --session-id / --model / --thinking argument; (4) the stdin pipe was closed due to a broken pipe after child death.
Common situations: pi CLI version too old to support `--mode rpc`; invalid flag combination (e.g. unknown --model or --thinking value) causing immediate exit; pi crashing on startup due to corrupt config or missing API key, closing stdin before the probe lands.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/3eaa3430b496b450.
Report an issue: GitHub.