{"id":"165ae3669eacc1ca","repo":"jackc/pgx","slug":"too-many-parameter-format-codes","errorCode":null,"errorMessage":"too many parameter format codes","messagePattern":"too many parameter format codes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgproto3/bind.go","lineNumber":122,"sourceCode":"\tfor i := range resultFormatCodeCount {\n\t\tdst.ResultFormatCodes[i] = int16(binary.BigEndian.Uint16(src[rp:]))\n\t\trp += 2\n\t}\n\n\treturn nil\n}\n\n// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.\nfunc (src *Bind) Encode(dst []byte) ([]byte, error) {\n\tdst, sp := beginMessage(dst, 'B')\n\n\tdst = append(dst, src.DestinationPortal...)\n\tdst = append(dst, 0)\n\tdst = append(dst, src.PreparedStatement...)\n\tdst = append(dst, 0)\n\n\tif len(src.ParameterFormatCodes) > math.MaxUint16 {\n\t\treturn nil, errors.New(\"too many parameter format codes\")\n\t}\n\tdst = pgio.AppendUint16(dst, uint16(len(src.ParameterFormatCodes)))\n\tfor _, fc := range src.ParameterFormatCodes {\n\t\tdst = pgio.AppendInt16(dst, fc)\n\t}\n\n\tif len(src.Parameters) > math.MaxUint16 {\n\t\treturn nil, errors.New(\"too many parameters\")\n\t}\n\tdst = pgio.AppendUint16(dst, uint16(len(src.Parameters)))\n\tfor _, p := range src.Parameters {\n\t\tif p == nil {\n\t\t\tdst = pgio.AppendInt32(dst, -1)\n\t\t\tcontinue\n\t\t}\n\n\t\tdst = pgio.AppendInt32(dst, int32(len(p)))\n\t\tdst = append(dst, p...)","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgproto3/bind.go#L104-L140","documentation":"Returned by Bind.Encode in pgproto3/bind.go:122 when len(src.ParameterFormatCodes) exceeds 65535 (math.MaxUint16). The wire protocol encodes the parameter-format-code count as a uint16, so more than 65535 codes cannot be serialized. This is a caller-side guard fired while building the Bind message to send to the server, before any network I/O.","triggerScenarios":"Constructing a Bind (or an extended-query ExecParams/ExecPrepared/Batch) with more than 65535 parameter format codes. In practice this means an explicit ParameterFormatCodes slice exceeding the limit, almost always an application bug since pgx normally generates at most one code per parameter.","commonSituations":"A query with an enormous IN-list or bulk insert built with >65535 placeholders; programmatically generating format codes in a loop without a cap; copying a result-set column count into format codes by mistake.","solutions":["Cap ParameterFormatCodes at 65535; for uniform formats use a single code (the protocol applies one code to all params when count is 1).","Batch the operation: split the query into chunks of <=65535 parameters.","For bulk inserts, use COPY (pgx CopyFrom) instead of parameterized inserts."],"exampleFix":"// before: one format code per parameter, blows past 65535\nformats := make([]int16, 100000) // -> \"too many parameter format codes\"\n\n// after: a single code applies to all parameters (protocol rule)\nformats := []int16{0} // text format for every parameter","handlingStrategy":"validation","validationCode":"const maxFormatCodes = 65535 // math.MaxUint16\nif len(parameterFormatCodes) > maxFormatCodes {\n    // Use a single code: the protocol applies one code to ALL parameters.\n    parameterFormatCodes = []int16{parameterFormatCodes[0]}\n}","typeGuard":"func bindFormatCodesOK(codes []int16) bool { return len(codes) <= 65535 }","tryCatchPattern":"if _, err := bindMsg.Encode(dst); err != nil {\n    if strings.Contains(err.Error(), \"too many parameter format codes\") {\n        // collapse to a single uniform code, or split the batch\n        bindMsg.ParameterFormatCodes = []int16{bindMsg.ParameterFormatCodes[0]}\n    }\n}","preventionTips":["Use at most one ParameterFormatCode when all parameters share a format (protocol applies it to all).","Split large batches so each Bind carries <=65535 entries.","Add a unit assertion that generated format-code slices stay under 65535."],"tags":["bind","protocol","encode","parameter-limit","pgproto3"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}