{"record":{"id":"dd7ff8b9bf907d56","repo":"plandex-ai/plandex","slug":"error-parsing-request-body","errorCode":null,"errorMessage":"Error parsing request body ","messagePattern":"Error parsing request body ","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"app/server/handlers/branches.go","lineNumber":113,"sourceCode":"\tif plan == nil {\n\t\treturn\n\t}\n\n\tbody, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\tlog.Printf(\"Error reading request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error reading request body\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer func() {\n\t\tlog.Println(\"Closing request body\")\n\t\tr.Body.Close()\n\t}()\n\n\tvar req shared.CreateBranchRequest\n\tif err := json.Unmarshal(body, &req); err != nil {\n\t\tlog.Printf(\"Error parsing request body: %v\\n\", err)\n\t\thttp.Error(w, \"Error parsing request body \", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tparentBranch, err := db.GetDbBranch(planId, branch)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error getting parent branch: %v\\n\", err)\n\t\thttp.Error(w, \"Error getting parent branch: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithCancel(r.Context())\n\n\terr = db.ExecRepoOperation(db.ExecRepoOperationParams{\n\t\tOrgId:    auth.OrgId,\n\t\tUserId:   auth.User.Id,\n\t\tPlanId:   planId,\n\t\tBranch:   \"main\",","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/branches.go#L95-L131","documentation":"CreateBranchHandler unmarshals the request body into shared.CreateBranchRequest and returns HTTP 400 'Error parsing request body' when json.Unmarshal fails. This is a client-side payload problem: the body is not valid JSON or does not match the expected structure. The server deliberately responds 400 (client error), not 500.","triggerScenarios":"POST with a body that is not valid JSON (syntax errors, empty body, HTML error page from a proxy), wrong Content-Type causing a garbled body, or fields of the wrong type (e.g. \"name\": 123 instead of a string).","commonSituations":"Calling the API with curl and forgetting to quote/single-quote the JSON on the shell; sending form-encoded data instead of JSON; an API client version mismatch where the request struct changed; a proxy returning an HTML 502 page as the body.","solutions":["Validate the request body is well-formed JSON matching shared.CreateBranchRequest (name field as string)","Set Content-Type: application/json and send the serialized struct, not raw text","Check for client/server API version mismatch on CreateBranchRequest fields","Test with curl -d '{\"name\":\"my-branch\"}' -H 'Content-Type: application/json'"],"exampleFix":"// before\nhttp.Post(url, \"text/plain\", strings.NewReader(`{\"name\": \"b\"}`))\n// after\nhttp.Post(url, \"application/json\", bytes.NewBuffer([]byte(`{\"name\":\"b\"}`)))","handlingStrategy":"validation","validationCode":"// client: validate JSON before sending\nbody, err := json.Marshal(shared.CreateBranchRequest{Name: branchName})\nif err != nil { return fmt.Errorf(\"invalid request: %w\", err) }\nif !json.Valid(body) { return errors.New(\"payload is not valid JSON\") }","typeGuard":"func isValidCreateBranchRequest(b []byte) bool {\n    var req shared.CreateBranchRequest\n    return json.Unmarshal(b, &req) == nil && req.Name != \"\"\n}","tryCatchPattern":"// check response status before decoding a success shape\nif resp.StatusCode == http.StatusBadRequest {\n    var errResp struct{ Error string }\n    _ = json.NewDecoder(resp.Body).Decode(&errResp)\n    return fmt.Errorf(\"bad request: %s\", errResp.Error)\n}","preventionTips":["Always marshal a typed struct instead of hand-writing JSON strings","Set Content-Type: application/json","Validate JSON with json.Valid or a schema before sending","Quote JSON payloads correctly in shell/curl commands"],"tags":["json","validation","http-400","request"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}