{"record":{"id":"c389b923cc5f7337","repo":"chenhg5/cc-connect","slug":"start-w","errorCode":null,"errorMessage":"start: %w","messagePattern":"start: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"agent/pi/session.go","lineNumber":210,"sourceCode":"\tcmd.Env = env\n\n\tstdinPipe, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"stdin pipe: %w\", err)\n\t}\n\ts.rpcStdin = stdinPipe\n\ts.rpcCmd = cmd\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"stdout pipe: %w\", err)\n\t}\n\tcmd.Stderr = &s.stderrBuf\n\n\tprepareCmdForKill(cmd)\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"start: %w\", err)\n\t}\n\n\ts.wg.Add(1)\n\tgo s.readLoopRPC(stdout)\n\n\t// Pi's RPC protocol does not push a \"session\" event on stdout — the only\n\t// way to learn the session id is to send {\"type\":\"get_state\"} and parse\n\t// the matching response in handleEvent. We probe immediately after spawn\n\t// so that newPiSession's wait on rpcReady only unblocks once the id has\n\t// been stored. readLoopRPC closes rpcReady as soon as sessionIDReady()\n\t// flips to true (which happens after handleEvent processes the response),\n\t// so callers can safely read CurrentSessionID() the moment rpcReady fires.\n\t//\n\t// If the probe write fails, the session is unrecoverable: without the\n\t// session id we cannot resume after /stop, which is the very bug we are\n\t// fixing. Bail out immediately and let the caller surface the error\n\t// instead of waiting for the 30s rpcReady timeout.\n\tif err := s.writeRPCCommand(map[string]any{","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/pi/session.go#L192-L228","documentation":"agent/pi/session.go:210 — startRPC fails to spawn the persistent `pi --mode rpc` child process via cmd.Start() and wraps the OS/exec error with \"start: %w\". This error is returned synchronously to newPiSession, so session creation fails outright and no RPC session is created. It means the pi binary could not be executed at all (not found, not executable, or exec-level failure), not that pi crashed later.","triggerScenarios":"Calling core.CreateAgent(\"pi\",...) / newPiSession with rpc mode enabled when: (1) the configured `cmd` binary does not exist on PATH; (2) the file exists but lacks the executable bit; (3) exec fails due to resource limits (fork/exec ENOMEM, EAGAIN); (4) workDir (cmd.Dir) no longer exists.","commonSituations":"pi CLI not installed or installed under a different name than configured; config.toml points `cmd` at a relative path while the daemon's working directory differs; user upgraded the binary and permissions changed; Docker/systemd unit with a restricted PATH missing the pi install location.","solutions":["Verify the configured pi binary exists and is executable: `which <cmd>` and `ls -l $(which <cmd>)`; install pi or fix the `cmd` value in config.toml to an absolute path.","Check that the session's workDir exists and is accessible by the user running cc-connect.","Run the exact command the agent would run (`pi --mode rpc`) manually in the configured workDir to reproduce the exec failure outside the daemon.","If running under systemd/Docker, fix PATH or binary permissions for the service user."],"exampleFix":"// config.toml\n# before\n[agents.pi]\ncmd = \"pi\"          # not on daemon PATH\n# after\n[agents.pi]\ncmd = \"/usr/local/bin/pi\"","handlingStrategy":"validation","validationCode":"bin := agentConfig.Cmd\nif p, err := exec.LookPath(bin); err != nil {\n    return fmt.Errorf(\"pi binary %q not found: %w\", bin, err)\n} else if fi, err := os.Stat(p); err != nil || fi.Mode()&0o111 == 0 {\n    return fmt.Errorf(\"pi binary %q is not executable\", p)\n}\nif _, err := os.Stat(workDir); err != nil {\n    return fmt.Errorf(\"workDir %q unavailable: %w\", workDir, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for agent binaries in config.toml, never bare names.","Run `cc-connect doctor` (or manually check the CLI binary) after installing/upgrading pi.","Keep the daemon's PATH and service-user permissions aligned with where pi is installed.","Ensure configured workDir exists before creating sessions."],"tags":["exec","process-spawn","go","agent-pi"],"backgroundTag":"command-not-found","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}