{"id":"d8695fc2577549bf","repo":"jackc/pgx","slug":"too-many-arguments","errorCode":null,"errorMessage":"too many arguments","messagePattern":"too many arguments","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgproto3/function_call.go","lineNumber":111,"sourceCode":"\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}\n\tdst = pgio.AppendUint16(dst, src.ResultFormatCode)\n\treturn finishMessage(dst, sp)\n}\n","sourceCodeStart":93,"sourceCodeEnd":125,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgproto3/function_call.go#L93-L125","documentation":"Returned by FunctionCall.Encode when Arguments has more than 65535 entries. The argument count is a uint16 on the wire, so MaxUint16 is the hard ceiling; the guard avoids a truncated count. FunctionCall is the legacy 'F' message for the v3 function-call protocol.","triggerScenarios":"Calling `(*FunctionCall).Encode(dst)` with `len(Arguments) > 65535`. Surfaces in synthetic code or a caller invoking a function with an enormous argument list.","commonSituations":"A caller bulk-converts a slice/map into FunctionCall arguments without bounding it, or a test harness stress-tests the encoder. Real PostgreSQL functions cannot accept >64k args, so this almost always indicates a construction bug.","solutions":["Cap Arguments at 65535; PostgreSQL function signatures cannot exceed this anyway.","Batch large argument sets into multiple calls or use array parameters instead of positional args.","Audit the loop building Arguments for an unbounded or duplicated append.","Add a pre-encode length check returning a clear error to the caller."],"exampleFix":"// before\nfc := &pgproto3.FunctionCall{\n    Function:  oid,\n    Arguments: hugeArgs, // > 65535\n}\n_, err := fc.Encode(nil)\n\n// after\nif len(hugeArgs) > 65535 {\n    return fmt.Errorf(\"too many function args: %d (max 65535)\", len(hugeArgs))\n}\nfc := &pgproto3.FunctionCall{Function: oid, Arguments: hugeArgs}\n_, err := fc.Encode(nil)","handlingStrategy":"validation","validationCode":"func validateFunctionCallArgs(fc *pgproto3.FunctionCall) error {\n\tif len(fc.Arguments) > math.MaxUint16 {\n\t\treturn fmt.Errorf(\"too many arguments: %d (max %d)\", len(fc.Arguments), math.MaxUint16)\n\t}\n\treturn nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Cap Arguments at 65535; PostgreSQL functions cannot exceed this anyway.","Batch large argument sets across calls or use array parameters.","Audit construction loops for unbounded appends."],"tags":["pgproto3","protocol","encoding","function-call","wire-protocol","validation"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}