{"id":"7b04d912180c9234","repo":"jackc/pgx","slug":"invalid-length-for-copybothresponse-overallformat","errorCode":null,"errorMessage":"invalid length for CopyBothResponse.OverallFormat","messagePattern":"invalid length for CopyBothResponse\\.OverallFormat","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgproto3/copy_both_response.go","lineNumber":89,"sourceCode":"}\n\n// UnmarshalJSON implements encoding/json.Unmarshaler.\nfunc (dst *CopyBothResponse) UnmarshalJSON(data []byte) error {\n\t// Ignore null, like in the main JSON package.\n\tif string(data) == \"null\" {\n\t\treturn nil\n\t}\n\n\tvar msg struct {\n\t\tOverallFormat     string\n\t\tColumnFormatCodes []uint16\n\t}\n\tif err := json.Unmarshal(data, &msg); err != nil {\n\t\treturn err\n\t}\n\n\tif len(msg.OverallFormat) != 1 {\n\t\treturn errors.New(\"invalid length for CopyBothResponse.OverallFormat\")\n\t}\n\n\tdst.OverallFormat = msg.OverallFormat[0]\n\tdst.ColumnFormatCodes = msg.ColumnFormatCodes\n\treturn nil\n}\n","sourceCodeStart":71,"sourceCodeEnd":96,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgproto3/copy_both_response.go#L71-L96","documentation":"Returned by CopyBothResponse.UnmarshalJSON when the JSON `OverallFormat` field is not exactly one character long. OverallFormat is a single byte on the wire (0 = text, 1 = binary), so the JSON form must be a one-character string. An empty string, a multi-char value, or a numeric literal fails this check.","triggerScenarios":"Calling `json.Unmarshal(data, &copyBoth)` on JSON where `OverallFormat` has length != 1 — e.g. `{\"OverallFormat\": \"text\"}` or `{\"OverallFormat\": 0}` (number, not string).","commonSituations":"Test fixtures or replay tools serialise OverallFormat as a word (\"text\"/\"binary\") or as a JSON number instead of the one-char string the unmarshaler expects. Also seen when a hand-edited fixture leaves the field empty.","solutions":["Use the single-character wire form: \"0\" for text, \"1\" for binary.","Map full words before unmarshalling: `\"text\" -> \"0\"`, `\"binary\" -> \"1\"`.","Regenerate fixtures from MarshalJSON output so the field shape matches.","Pre-validate the JSON with a schema requiring a one-char string for OverallFormat."],"exampleFix":"// before\nraw := []byte(`{\"OverallFormat\":\"text\",\"ColumnFormatCodes\":[0]}`)\nerr := json.Unmarshal(raw, &cb) // error\n\n// after\nraw := []byte(`{\"OverallFormat\":\"0\",\"ColumnFormatCodes\":[0]}`)\nerr := json.Unmarshal(raw, &cb)","handlingStrategy":"validation","validationCode":"func validateCopyBothOverallFormat(raw []byte) error {\n\tvar probe struct{ OverallFormat string }\n\tif err := json.Unmarshal(raw, &probe); err != nil { return err }\n\tif len(probe.OverallFormat) != 1 {\n\t\treturn fmt.Errorf(\"OverallFormat must be one char (\\\"0\\\"/\\\"1\\\"), got %q\", probe.OverallFormat)\n\t}\n\treturn nil\n}","typeGuard":"func isValidCopyOverallFormat(s string) bool {\n\treturn len(s) == 1 && (s == \"0\" || s == \"1\")\n}","tryCatchPattern":"var cb pgproto3.CopyBothResponse\nif err := json.Unmarshal(raw, &cb); err != nil {\n    // tell caller OverallFormat must be \"0\" (text) or \"1\" (binary)\n    return err\n}","preventionTips":["Emit OverallFormat as the single wire character \"0\" (text) or \"1\" (binary).","Generate fixtures from MarshalJSON.","Reject numeric OverallFormat in incoming JSON and map words to codes before unmarshalling."],"tags":["pgproto3","json","serialization","validation","copy","replication"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}