chenhg5/cc-connect · warning
piSession: marshal command: %w
Error message
piSession: marshal command: %w
What it means
agent/pi/session.go:454 — writeRPCCommand marshals the command map to JSON before writing it to the RPC stdin; if json.Marshal fails it returns "piSession: marshal command: %w". The commands built by this library (get_state probe, prompt commands) are plain map[string]any of JSON-safe values, so this nearly always indicates non-serializable data (channels, funcs, or invalid values like NaN) injected into the command payload — e.g. via prompt or attachment path content.
Source
Thrown at agent/pi/session.go:454
}
sid := s.CurrentSessionID()
evt := core.Event{Type: core.EventResult, SessionID: sid, Done: true}
select {
case s.events <- evt:
case <-s.ctx.Done():
}
return nil
}
// writeRPCCommand marshals cmd as a single JSONL line and writes it to the
// RPC process's stdin under rpcStdinMu. Used by both sendRPC (for "prompt"
// commands during a turn) and startRPC (for the startup "get_state" probe
// that fetches the session id before callers are released).
func (s *piSession) writeRPCCommand(cmd map[string]any) error {
b, err := json.Marshal(cmd)
if err != nil {
return fmt.Errorf("piSession: marshal command: %w", err)
}
b = append(b, '\n')
s.rpcStdinMu.Lock()
_, err = s.rpcStdin.Write(b)
s.rpcStdinMu.Unlock()
if err != nil {
return fmt.Errorf("piSession: write stdin: %w", err)
}
return nil
}
// sendRPC writes a JSON "prompt" command to the persistent RPC process stdin.
// Events are read asynchronously by readLoopRPC, including agent_end which
// triggers EventResult.
//
// Issue #1723: image paths are embedded into the message text as
// @<path> references (pi's standard mechanism, parsed the same way as inView on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped json error (UnsupportedTypeError names the offending Go type) and remove/convert that value.
- Sanitize payload values: ensure prompt text, image paths, and file paths are plain strings.
- Replace NaN/Inf floats with strings or omit them from the command map.
- If you maintain custom pi-agent code, validate the command with json.Marshal in a test before calling writeRPCCommand.
Example fix
// before
cmd := map[string]any{"type": "prompt", "message": msg, "cb": callback} // func not marshalable
// after
cmd := map[string]any{"type": "prompt", "message": msg} Defensive patterns
Strategy: validation
Validate before calling
func validateRPCCommand(cmd map[string]any) error {
if _, err := json.Marshal(cmd); err != nil {
return fmt.Errorf("command not JSON-serializable: %w", err)
}
return nil
} Try / catch
if err := validateRPCCommand(cmdMap); err != nil {
return fmt.Errorf("refusing to send invalid RPC command: %w", err)
}
if err := writeRPCCommand(cmdMap); err != nil {
if strings.Contains(err.Error(), "marshal command:") {
slog.Error("RPC command marshal failed; sanitize payload", "err", err)
}
return err
} Prevention
- Keep RPC command payloads to JSON-safe types (string, number, bool, slice, map).
- Never insert chan/func/complex values into command maps, even in internal tooling.
- Convert NaN/Inf floats to strings or omit them.
- Add a unit test that marshals every command variant the agent can emit.
When it happens
Trigger: writeRPCCommand is called by startRPC (get_state probe) and sendRPC (prompt commands); marshal fails when: (1) a value in the command map is not JSON-marshalable (chan, func, complex); (2) an unsupported value type slips in via extra args/attachment lists; (3) json.Marshal returns json.UnsupportedTypeError / UnsupportedValueError for float NaN/Inf.
Common situations: Custom code or a fork injecting non-JSON-safe fields into the prompt command; NaN/Inf values propagated into the payload; misuse of the internal API by plugin/extension code building commands with richer types.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- marshal: %w
- marshal: %w
- piSession: write get_state probe: %w
- pi: %s
- piSession: marshal extension_ui_response: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/e93e43c4ec9d8deb.
Report an issue: GitHub.