chenhg5/cc-connect · error
invalid Content-Length: %w
Error message
invalid Content-Length: %w
What it means
The header line 'Content-Length: <val>' was found but its value could not be parsed as an integer (strconv.Atoi failed). The copilot peer sent a malformed Content-Length header, violating the LSP framing protocol, so the message cannot be framed or read safely.
Source
Thrown at agent/copilot/jsonrpc.go:104
// readMessage reads one Content-Length framed message and returns the raw JSON body.
func (lr *lspReader) readMessage() ([]byte, error) {
contentLength := -1
for {
line, err := lr.reader.ReadString('\n')
if err != nil {
return nil, fmt.Errorf("read header: %w", err)
}
line = strings.TrimRight(line, "\r\n")
if line == "" {
// End of headers
break
}
if strings.HasPrefix(line, "Content-Length: ") {
val := strings.TrimPrefix(line, "Content-Length: ")
n, err := strconv.Atoi(strings.TrimSpace(val))
if err != nil {
return nil, fmt.Errorf("invalid Content-Length: %w", err)
}
contentLength = n
}
// Ignore other headers (Content-Type, etc.)
}
if contentLength < 0 {
return nil, fmt.Errorf("missing Content-Length header")
}
if contentLength > 10*1024*1024 {
return nil, fmt.Errorf("Content-Length too large: %d", contentLength)
}
body := make([]byte, contentLength)
if _, err := io.ReadFull(lr.reader, body); err != nil {
return nil, fmt.Errorf("read body: %w", err)
}
return body, nilView on GitHub (pinned to 4000b2338a)
Solutions
- Check whether the copilot binary or a wrapper script pollutes stdout with non-LSP output and route logs to stderr
- Upgrade/downgrade the copilot CLI to a conforming version
- Test with runMockCopilot to reproduce the exact header bytes being sent
- If a wrapper is used, strip non-LSP lines before they reach the framing reader
Example fix
// before (mock emits bad header) fmt.Fprintf(w, "Content-Length: %s\r\n\r\n", len(body)) // %s on int -> bad // after fmt.Fprintf(w, "Content-Length: %d\r\n\r\n", len(body))
Defensive patterns
Strategy: validation
Validate before calling
// validate a header line before parsing
func parseContentLength(line string) (int, error) {
val := strings.TrimSpace(strings.TrimPrefix(line, "Content-Length: "))
if val == "" { return 0, errors.New("empty Content-Length") }
n, err := strconv.Atoi(val)
if err != nil || n < 0 { return 0, fmt.Errorf("bad Content-Length %q", val) }
return n, nil
} Try / catch
if _, err := reader.readMessage(); err != nil && strings.Contains(err.Error(), "invalid Content-Length") {
slog.Error("peer sent malformed LSP header — check for stdout pollution", "err", err)
// fail fast; do not attempt to resync framing
} Prevention
- Keep stdout strictly LSP-framed: logs/warnings go to stderr
- Test CLI upgrades against runMockCopilot-style golden frames
- Reject wrapper scripts that echo extra text on stdout
When it happens
Trigger: readMessage parsing a header like 'Content-Length: abc' or with garbage after the number from the copilot process stdout — emitted when a non-conforming CLI writes junk to stdout.
Common situations: A copilot CLI version (or wrapper script) printing log lines interleaved with LSP frames on stdout; a mock/debug shim emitting malformed headers; locale/encoding issues injecting characters into the header.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- missing Content-Length header
- Content-Length too large: %d
- invalid permission decision %q
- parse %s: %w
- parse hook output: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cce2f69d59a5b548.
Report an issue: GitHub.