{"record":{"id":"ddd66a082f8ed3cb","repo":"grafana/k6","slug":"invalid-grpc-s-client-invoke-parameters-w","errorCode":null,"errorMessage":"invalid GRPC's client.invoke() parameters: %w","messagePattern":"invalid GRPC's client\\.invoke\\(\\) parameters: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/client.go","lineNumber":371,"sourceCode":"\t\treturn grpcReq, common.NewInitContextError(\"invoking RPC methods in the init context is not supported\")\n\t}\n\tif c.conn == nil {\n\t\treturn grpcReq, errors.New(\"no gRPC connection, you must call connect first\")\n\t}\n\tif method == \"\" {\n\t\treturn grpcReq, errors.New(\"method to invoke cannot be empty\")\n\t}\n\tif method[0] != '/' {\n\t\tmethod = \"/\" + method\n\t}\n\tmethodDesc := c.mds[method]\n\tif methodDesc == nil {\n\t\treturn grpcReq, fmt.Errorf(\"method %q not found in file descriptors\", method)\n\t}\n\n\tp, err := newCallParams(c.vu, params)\n\tif err != nil {\n\t\treturn grpcReq, fmt.Errorf(\"invalid GRPC's client.invoke() parameters: %w\", err)\n\t}\n\n\t// k6 GRPC Invoke's default timeout is 2 minutes\n\tif p.Timeout == time.Duration(0) {\n\t\tp.Timeout = 2 * time.Minute\n\t}\n\n\tif req == nil {\n\t\treturn grpcReq, errors.New(\"request cannot be nil\")\n\t}\n\n\tobject := req.ToObject(c.vu.Runtime())\n\n\tvar stack []*sobek.Object\n\tnormalized, err := normalizeNumberStrings(object, c.vu.Runtime(), stack)\n\tif err != nil {\n\t\treturn grpcReq, fmt.Errorf(\"unable to normalize number strings: %w\", err)\n\t}","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/client.go#L353-L389","documentation":"The third argument of client.invoke() (also used by new grpc.Stream) is validated by newCallParams; failures are wrapped as \"invalid GRPC's client.invoke() parameters: <cause>\" (internal/js/modules/k6/grpc/client.go:371). Causes: 'unknown param: <key>' (allowed keys are metadata, tags, timeout, discardResponseMessage), 'invalid metadata param' (metadata must be an object; non '-bin' values must be strings, '-bin' keys need binary values), 'metric tags', or 'invalid timeout value' (duration string or millisecond number).","triggerScenarios":"client.invoke(m, req, { metada: {...} }) (typo -> unknown param); client.invoke(m, req, { metadata: { 'x-count': 5 } }) (number instead of string); client.invoke(m, req, { timeout: '10 seconds' }) (unparseable duration).","commonSituations":"Passing numeric metadata values straight from JS variables without String(); assuming the HTTP module's option formats apply; typo'd keys in large param objects.","solutions":["Fix the wrapped cause: correct the key name, stringify metadata values, use duration strings like '500ms'","Keep only metadata, tags, timeout, discardResponseMessage in invoke params","For binary metadata use keys ending in -bin with byte values (e.g. from k6/encoding)"],"exampleFix":"// before\nclient.invoke(method, req, { metadata: { 'x-count': 5 } });\n\n// after\nclient.invoke(method, req, { metadata: { 'x-count': String(5) } });","handlingStrategy":"validation","validationCode":"const CALL_KEYS = new Set(['metadata','tags','timeout','discardResponseMessage']);\nfunction assertCallParams(p = {}) {\n  for (const k of Object.keys(p)) {\n    if (!CALL_KEYS.has(k)) throw new Error(`unknown invoke param: ${k}`);\n  }\n  for (const [k, v] of Object.entries(p.metadata || {})) {\n    if (!k.endsWith('-bin') && typeof v !== 'string') throw new Error(`metadata[${k}] must be a string`);\n  }\n  return p;\n}\nclient.invoke(method, req, assertCallParams(params));","typeGuard":null,"tryCatchPattern":"try { client.invoke(m, req, params); } catch (e) { if (/invalid GRPC's client.invoke\\(\\) parameters/.test(e.message)) { /* wrapped cause names the bad key/value; fix and retry */ } throw e; }","preventionTips":["Only metadata, tags, timeout, discardResponseMessage are accepted","Stringify metadata values explicitly","Binary metadata needs a -bin key with byte values"],"tags":["grpc","k6","validation","invoke","metadata"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}