{"record":{"id":"4401b399b2cd9c84","repo":"grafana/k6","slug":"invalid-grpc-connect-parameters-w","errorCode":null,"errorMessage":"invalid grpc.connect() parameters: %w","messagePattern":"invalid grpc\\.connect\\(\\) parameters: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/client.go","lineNumber":227,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t} else if caCertStr, caCertStrOk := cas.(string); caCertStrOk {\n\t\t\tca = [][]byte{[]byte(caCertStr)}\n\t\t}\n\t}\n\treturn buildTLSConfig(parentConfig, cert, key, ca)\n}\n\n// Connect is a block dial to the gRPC server at the given address (host:port)\nfunc (c *Client) Connect(addr string, params sobek.Value) (bool, error) {\n\tstate := c.vu.State()\n\tif state == nil {\n\t\treturn false, common.NewInitContextError(\"connecting to a gRPC server in the init context is not supported\")\n\t}\n\n\tp, err := newConnectParams(c.vu, params)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"invalid grpc.connect() parameters: %w\", err)\n\t}\n\n\topts := grpcext.DefaultOptions(c.vu.State)\n\n\tvar tcred credentials.TransportCredentials\n\tif !p.IsPlaintext {\n\t\ttlsCfg := state.TLSConfig.Clone()\n\t\tif len(p.TLS) > 0 {\n\t\t\tif tlsCfg, err = buildTLSConfigFromMap(tlsCfg, p.TLS); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\ttlsCfg.NextProtos = []string{\"h2\"}\n\n\t\ttcred = credentials.NewTLS(tlsCfg)\n\t} else {\n\t\ttcred = insecure.NewCredentials()\n\t}","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/client.go#L209-L245","documentation":"grpc.connect() validates its params object with newConnectParams; any failure is wrapped as 'invalid grpc.connect() parameters: <cause>' (internal/js/modules/k6/grpc/client.go:227). The cause names the exact problem: 'unknown connect param: <key>' (typo or unsupported key), non-boolean plaintext/reflect, invalid timeout (needs a duration string like '10s' or a millisecond number), non-integer or negative maxReceiveSize/maxSendSize, non-string authority, invalid reflectMetadata, or a malformed tls object (expected keys cert, key, password, cacerts).","triggerScenarios":"connect(addr, { plaintext: 'true' }); connect(addr, { timeOut: 1000 }) (typo -> unknown param); connect(addr, { maxReceiveSize: '4MB' }) (string instead of integer bytes); connect(addr, { tls: 'cert.pem' }) (string instead of object).","commonSituations":"Copy-pasting option styles from the HTTP module (expecting '4MB' size strings); renames/additions between k6 versions; long param objects with typos that silently become 'unknown param'.","solutions":["Read the wrapped cause after the colon - it names the offending key and the expected type","Use only the documented keys: plaintext, timeout, reflect, reflectMetadata, maxReceiveSize, maxSendSize, tls, authority","Set sizes as plain integer bytes and timeout as '600ms' / '10s' style strings"],"exampleFix":"// before\nconnect(addr, { maxReceiveSize: '4MB', plaintext: 'true' });\n\n// after\nconnect(addr, { maxReceiveSize: 4 * 1024 * 1024, plaintext: true });","handlingStrategy":"validation","validationCode":"const CONNECT_KEYS = new Set(['plaintext','timeout','reflect','reflectMetadata','maxReceiveSize','maxSendSize','tls','authority']);\nfunction assertConnectParams(p) {\n  for (const k of Object.keys(p)) {\n    if (!CONNECT_KEYS.has(k)) throw new Error(`unknown connect param: ${k}`);\n  }\n  if (p.plaintext !== undefined && typeof p.plaintext !== 'boolean') throw new Error('plaintext must be boolean');\n  if (p.maxReceiveSize !== undefined && (!Number.isInteger(p.maxReceiveSize) || p.maxReceiveSize < 0)) throw new Error('maxReceiveSize must be a non-negative integer');\n  if (p.maxSendSize !== undefined && (!Number.isInteger(p.maxSendSize) || p.maxSendSize < 0)) throw new Error('maxSendSize must be a non-negative integer');\n  if (p.authority !== undefined && typeof p.authority !== 'string') throw new Error('authority must be a string');\n  return p;\n}\nclient.connect(addr, assertConnectParams(params));","typeGuard":null,"tryCatchPattern":"try { client.connect(addr, params); } catch (e) { if (/invalid grpc.connect\\(\\) parameters/.test(e.message)) { /* e.message's wrapped cause names the bad key; fix params and retry */ } throw e; }","preventionTips":["Sizes are integer bytes, not '4MB' strings","Timeouts are duration strings ('10s') or ms numbers","Keep params in one typed config object validated once at script start"],"tags":["grpc","k6","validation","options","connect"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}