chenhg5/cc-connect · error

invalid JSON:

Error message

invalid JSON: 

What it means

The request body could not be decoded into the WebhookRequest struct. The handler returns 400 with "invalid JSON: <detail>". The webhook expects a JSON object with fields like session_key, prompt/exec, project, event.

Source

Thrown at core/webhook.go:99

		defer cancel()
		_ = ws.server.Shutdown(ctx)
	}
}

func (ws *WebhookServer) handleHook(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "POST only", http.StatusMethodNotAllowed)
		return
	}

	if !ws.authenticate(r) {
		http.Error(w, "unauthorized", http.StatusUnauthorized)
		return
	}

	var req WebhookRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "invalid JSON: "+err.Error(), http.StatusBadRequest)
		return
	}

	if req.SessionKey == "" {
		http.Error(w, "session_key is required", http.StatusBadRequest)
		return
	}
	if req.Prompt == "" && req.Exec == "" {
		http.Error(w, "either prompt or exec is required", http.StatusBadRequest)
		return
	}
	if req.Prompt != "" && req.Exec != "" {
		http.Error(w, "prompt and exec are mutually exclusive", http.StatusBadRequest)
		return
	}

	engine, err := ws.resolveEngine(req.Project)
	if err != nil {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Validate the JSON payload locally before sending (jq . or a linter).
  2. Set Content-Type: application/json and send a JSON object body.
  3. Check for shell quoting issues — wrap the -d payload in single quotes.
  4. Read the appended err.Error() detail to pinpoint the syntax error position.

Example fix

// before
{"session_key": "s1", "prompt": "hi",}
// after
{"session_key": "s1", "prompt": "hi"}
Defensive patterns

Strategy: validation

Validate before calling

payload, _ := json.Marshal(WebhookRequest{SessionKey: key, Prompt: p})
var check map[string]any
if err := json.Unmarshal(payload, &check); err != nil {
    return fmt.Errorf("payload is not valid JSON: %w", err)
}

Type guard

func isBadRequest(resp *http.Response) bool { return resp != nil && resp.StatusCode == http.StatusBadRequest }

Try / catch

resp, err := http.Post(url, "application/json", bytes.NewReader(payload))
if err == nil && resp.StatusCode == 400 {
    b, _ := io.ReadAll(resp.Body)
    return fmt.Errorf("webhook rejected payload: %s", b) // includes 'invalid JSON: ...' detail
}

Prevention

When it happens

Trigger: Sending empty body, malformed JSON (trailing commas, unquoted keys), wrong Content-Type payloads (form-encoded), or non-object JSON like arrays/strings.

Common situations: curl -d without quotes mangling the JSON in the shell; sender serializing with a non-JSON content type; truncated body from a proxy; template rendering producing empty body.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/ad86a436a69a7651. Report an issue: GitHub.