{"record":{"id":"de155d77f00d15d5","repo":"AdguardTeam/AdGuardHome","slug":"decoding-json-w","errorCode":null,"errorMessage":"decoding json: %w","messagePattern":"decoding json: %w","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/dhcpd/http_unix.go","lineNumber":651,"sourceCode":"\t} else if found4 {\n\t\tresult.V4.OtherServer.Found = \"yes\"\n\t}\n\n\tif err6 != nil {\n\t\tresult.V6.OtherServer.Found = \"error\"\n\t\tresult.V6.OtherServer.Error = err6.Error()\n\t} else if found6 {\n\t\tresult.V6.OtherServer.Found = \"yes\"\n\t}\n}\n\n// parseLease parses a lease from r.  If there is no error returns DHCPServer\n// and *Lease.  r must be non-nil.\nfunc (s *server) parseLease(r io.Reader) (srv DHCPServer, lease *dhcpsvc.Lease, err error) {\n\tl := &leaseStatic{}\n\terr = json.NewDecoder(r).Decode(l)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"decoding json: %w\", err)\n\t}\n\n\tif !l.IP.IsValid() {\n\t\treturn nil, nil, errors.Error(\"invalid ip\")\n\t}\n\n\tl.IP = l.IP.Unmap()\n\n\tlease, err = l.toLease()\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"parsing: %w\", err)\n\t}\n\n\tif lease.IP.Is4() {\n\t\tsrv = s.srv4\n\t} else {\n\t\tsrv = s.srv6\n\t}","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/dhcpd/http_unix.go#L633-L669","documentation":"Returned by parseLease when the JSON body of a static-lease request (add/remove/update) cannot be decoded into leaseStatic. This is a client-side payload problem: malformed JSON, wrong types (e.g. IP given as a number), or truncation. Affects POST /control/dhcp/add_static_lease and friends.","triggerScenarios":"POSTing to add/remove/update static lease with body that is not valid JSON, has an unexpected field type, or an empty body; sending the IP as a JSON number instead of a string; missing Content-Length on a chunked truncated request.","commonSituations":"Hand-crafted curl requests with quoting mistakes; scripts written against an older API shape; proxies stripping or corrupting request bodies; passing a MAC with invalid characters in an unexpected field.","solutions":["Validate the JSON before sending: echo '$BODY' | jq . must succeed","Match the expected schema: {\"ip\":\"192.168.1.10\",\"hostname\":\"printer\",\"mac\":\"AA:BB:CC:DD:EE:FF\"} with ip as string","Ensure the Content-Type is application/json and the body is fully transmitted","Check the server log line for the exact decode error (syntax error vs type mismatch) to pinpoint the field"],"exampleFix":"// before\ncurl -X POST .../control/dhcp/add_static_lease -d '{\"ip\": 3232235786, \"mac\":\"AA:BB:CC:DD:EE:FF\"}'\n// -> 400 decoding json: json: cannot unmarshal number into Go struct field .ip of type string\n\n// after\ncurl -X POST .../control/dhcp/add_static_lease -d '{\"ip\":\"192.168.1.10\",\"mac\":\"AA:BB:CC:DD:EE:FF\"}'","handlingStrategy":"validation","validationCode":"var buf bytes.Buffer\n_ = json.NewEncoder(&buf).Encode(lease)\nif !json.Valid(buf.Bytes()) { /* fix payload before send */ }","typeGuard":null,"tryCatchPattern":"if err := addStaticLease(lease); err != nil {\n    if strings.Contains(err.Error(), \"decoding json\") {\n        // payload problem: re-validate body schema client-side (ip must be string)\n    }\n}","preventionTips":["Always send ip/mac/hostname as JSON strings","Marshal with a proper JSON encoder, don't hand-concatenate strings","Echo the body through a JSON validator in scripts before POSTing"],"tags":["dhcp","json","validation","api","static-lease"],"backgroundTag":"request-body-json-invalid","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}