{"id":"992bf58c5012313f","repo":"jackc/pgx","slug":"too-many-arg-format-codes","errorCode":null,"errorMessage":"too many arg format codes","messagePattern":"too many arg format codes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgproto3/function_call.go","lineNumber":103,"sourceCode":"\t// The format code for the function result. Must presently be zero (text) or one (binary).\n\tif len(src[rp:]) < 2 {\n\t\treturn &invalidMessageFormatErr{messageType: \"FunctionCall\"}\n\t}\n\tresultFormatCode := binary.BigEndian.Uint16(src[rp:])\n\tif resultFormatCode != 0 && resultFormatCode != 1 {\n\t\treturn &invalidMessageFormatErr{messageType: \"FunctionCall\"}\n\t}\n\tdst.ResultFormatCode = resultFormatCode\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 *FunctionCall) Encode(dst []byte) ([]byte, error) {\n\tdst, sp := beginMessage(dst, 'F')\n\tdst = pgio.AppendUint32(dst, src.Function)\n\n\tif len(src.ArgFormatCodes) > math.MaxUint16 {\n\t\treturn nil, errors.New(\"too many arg format codes\")\n\t}\n\tdst = pgio.AppendUint16(dst, uint16(len(src.ArgFormatCodes)))\n\tfor _, argFormatCode := range src.ArgFormatCodes {\n\t\tdst = pgio.AppendUint16(dst, argFormatCode)\n\t}\n\n\tif len(src.Arguments) > math.MaxUint16 {\n\t\treturn nil, errors.New(\"too many arguments\")\n\t}\n\tdst = pgio.AppendUint16(dst, uint16(len(src.Arguments)))\n\tfor _, argument := range src.Arguments {\n\t\tif argument == nil {\n\t\t\tdst = pgio.AppendInt32(dst, -1)\n\t\t} else {\n\t\t\tdst = pgio.AppendInt32(dst, int32(len(argument)))\n\t\t\tdst = append(dst, argument...)\n\t\t}\n\t}","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgproto3/function_call.go#L85-L121","documentation":"Returned by FunctionCall.Encode when ArgFormatCodes has more than 65535 entries. The count is encoded as a uint16, so MaxUint16 is the ceiling; the guard prevents a truncated count. FunctionCall is the legacy 'F' message (the v3 function-call protocol), where each entry is 0 (text) or 1 (binary).","triggerScenarios":"Calling `(*FunctionCall).Encode(dst)` with `len(ArgFormatCodes) > 65535`. Realistic only in synthetic code, a fuzzer, or a caller that builds one format code per argument for a function with >64k args.","commonSituations":"The function-call protocol is rarely used by modern applications (prepared statements are preferred). A caller migrating an old libpq-style codebase that calls a function with a huge argument list, or a test harness stress-testing the encoder, could hit this. More often it signals a loop that over-appends.","solutions":["Cap ArgFormatCodes at 65535; a single-entry slice applies the format to all arguments (the protocol explicitly allows this).","Audit the construction loop for accidental duplication or per-row instead of per-arg appends.","Prefer a single format code shared by all arguments when formats are uniform.","Pre-validate length before encoding and return a clear error."],"exampleFix":"// before\nfc := &pgproto3.FunctionCall{\n    Function:       oid,\n    ArgFormatCodes: perArgCodes, // > 65535\n}\n_, err := fc.Encode(nil)\n\n// after\nfc := &pgproto3.FunctionCall{\n    Function:       oid,\n    ArgFormatCodes: []uint16{0}, // one code applies to all args\n}\n_, err := fc.Encode(nil)","handlingStrategy":"validation","validationCode":"func validateFunctionCallFormatCodes(fc *pgproto3.FunctionCall) error {\n\tif len(fc.ArgFormatCodes) > math.MaxUint16 {\n\t\treturn fmt.Errorf(\"too many arg format codes: %d (max %d)\", len(fc.ArgFormatCodes), math.MaxUint16)\n\t}\n\treturn nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Use a single ArgFormatCodes entry when all args share a format (protocol allows it).","Cap format-code slices at 65535 at construction.","Audit loops for per-row instead of per-arg appends."],"tags":["pgproto3","protocol","encoding","function-call","wire-protocol","validation"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}