chenhg5/cc-connect · error
marshal: %w
Error message
marshal: %w
What it means
writeJSON wraps a json.Marshal failure as 'marshal: %w'. The payload constructed by Send (user message with images/files) or RespondPermission (permission result) could not be serialized to JSON. In practice this is rare for these structurally-typed maps and usually indicates non-serializable values injected into the payload (e.g. NaN/infinite floats, channels, funcs) via UpdatedInput or attachments.
Source
Thrown at agent/claudecode/session.go:1095
"type": "control_response",
"response": map[string]any{
"subtype": "success",
"request_id": requestID,
"response": permResponse,
},
}
slog.Debug("claudeSession: permission response", "request_id", requestID, "behavior", result.Behavior)
return cs.writeJSON(controlResponse)
}
func (cs *claudeSession) writeJSON(v any) error {
cs.stdinMu.Lock()
defer cs.stdinMu.Unlock()
data, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("marshal: %w", err)
}
if _, err := cs.stdin.Write(append(data, '\n')); err != nil {
return fmt.Errorf("write stdin: %w", err)
}
return nil
}
func isClaudeEditTool(toolName string) bool {
switch toolName {
case "Edit", "Write", "NotebookEdit", "MultiEdit":
return true
default:
return false
}
}
func (cs *claudeSession) setPermissionMode(mode string) {
cs.permissionMode.Store(mode)View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped error's path (json.UnsupportedTypeError names the field) and sanitize/convert that value to a serializable type (string, float64, etc.)
- In RespondPermission, ensure UpdatedInput only carries map[string]any / primitives — coerce or drop exotic values before assigning
- Log the payload type at debug level to find which caller (Send vs RespondPermission) produced the bad value
- Fix at the source: validate permission results before calling RespondPermission
Example fix
// before
result.UpdatedInput = rawToolInput // may contain NaN / unsupported types
// after
safe, err := sanitizeJSONValue(rawToolInput)
if err != nil {
return fmt.Errorf("sanitize updated input: %w", err)
}
result.UpdatedInput = safe Defensive patterns
Strategy: validation
Validate before calling
// validate payloads are JSON-safe before calling Send/RespondPermission
func jsonSafe(v any) error {
_, err := json.Marshal(v)
return err // surfaces UnsupportedTypeError with the offending path
}
// usage: if err := jsonSafe(result.UpdatedInput); err != nil { return err } Try / catch
if err := sess.RespondPermission(reqID, result); err != nil {
var ue *json.UnsupportedTypeError
if errors.As(err, &ue) && strings.Contains(err.Error(), "marshal") {
log.Warn("non-serializable value in permission result", "field", ue.Value)
result.UpdatedInput = coerceToPrimitives(result.UpdatedInput)
err = sess.RespondPermission(reqID, result)
}
} Prevention
- Restrict UpdatedInput and attachment metadata to map[string]any with primitives
- Never pass values produced by decoding into interface{} straight from binary/custom formats without coercion
- Sanitize floats (reject NaN/Inf) before building payloads
- Round-trip test permission payloads with json.Marshal in unit tests
When it happens
Trigger: Send with images/files whose metadata fields contain unsupported types; RespondPermission with result.UpdatedInput populated from parsed tool input containing values json.Marshal rejects (NaN, cyclic structures, func values).
Common situations: Tool input round-tripped through custom parsers storing unusual types; plugins/agent code inserting unsupported values into UpdatedInput; custom image/file attachment structs with non-serializable fields.
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
- piSession: marshal command: %w
- piSession: marshal extension_ui_response: %w
- mimo tts: marshal request: %w
- marshal payload: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/276bfa3587983fac.
Report an issue: GitHub.