{"record":{"id":"8886526db6f110d9","repo":"grafana/k6","slug":"invalid-metadata-param-w","errorCode":null,"errorMessage":"invalid metadata param: %w","messagePattern":"invalid metadata param: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/params.go","lineNumber":47,"sourceCode":"func newCallParams(vu modules.VU, input sobek.Value) (*callParams, error) {\n\tresult := &callParams{\n\t\tMetadata:    metadata.New(nil),\n\t\tTagsAndMeta: vu.State().Tags.GetCurrentValues(),\n\t}\n\n\tif common.IsNullish(input) {\n\t\treturn result, nil\n\t}\n\n\trt := vu.Runtime()\n\tparams := input.ToObject(rt)\n\n\tfor _, k := range params.Keys() {\n\t\tswitch k {\n\t\tcase \"metadata\":\n\t\t\tmd, err := newMetadata(params.Get(k))\n\t\t\tif err != nil {\n\t\t\t\treturn result, fmt.Errorf(\"invalid metadata param: %w\", err)\n\t\t\t}\n\n\t\t\tresult.Metadata = md\n\t\tcase \"tags\":\n\t\t\tif err := common.ApplyCustomUserTags(rt, &result.TagsAndMeta, params.Get(k)); err != nil {\n\t\t\t\treturn result, fmt.Errorf(\"metric tags: %w\", err)\n\t\t\t}\n\t\tcase \"timeout\":\n\t\t\tvar err error\n\t\t\tv := params.Get(k).Export()\n\t\t\tresult.Timeout, err = types.GetDurationValue(v)\n\t\t\tif err != nil {\n\t\t\t\treturn result, fmt.Errorf(\"invalid timeout value: %w\", err)\n\t\t\t}\n\t\tcase \"discardResponseMessage\":\n\t\t\tresult.DiscardResponseMessage = params.Get(k).ToBoolean()\n\t\tdefault:\n\t\t\treturn result, fmt.Errorf(\"unknown param: %q\", k)","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/params.go#L29-L65","documentation":"params.metadata on client.invoke() or new grpc.Stream() is parsed by newMetadata(): it must be a plain object mapping header names to values. Keys ending in -bin must map to binary values ([]byte from JS: Uint8Array/ArrayBuffer); all other keys must map to strings. A non-object value, or any value of the wrong type, fails and is rethrown wrapped as 'invalid metadata param'.","triggerScenarios":"metadata: 'authorization=token' (a string instead of an object); metadata: ['a', 'b'] (an array); { 'trace-id-bin': 'xyz' } (string for a -bin key); { count: 5 } (number for a normal key).","commonSituations":"Porting HTTP header strings or curl-style 'k: v' syntax; passing base64 strings where the server expects binary metadata; numbers and booleans not stringified before being spread into metadata.","solutions":["Pass a plain object: { authorization: 'token' }","Give -bin keys Uint8Array values (e.g. new Uint8Array([2, 200]))","Stringify non-string scalars: String(count)"],"exampleFix":"// before\nclient.invoke(method, req, { metadata: { 'x-load-tester-bin': 'buffer' } });\n\n// after\nclient.invoke(method, req, { metadata: { 'x-load-tester-bin': new Uint8Array([2, 200]) } });","handlingStrategy":"type-guard","validationCode":"assertGrpcMetadata(params.metadata);\nclient.invoke(method, req, params);","typeGuard":"function assertGrpcMetadata(obj, where = 'metadata') {\n  if (obj == null) return true;\n  if (typeof obj !== 'object' || Array.isArray(obj)) {\n    throw new Error(`${where} must be a plain object of key-value pairs`);\n  }\n  for (const [k, v] of Object.entries(obj)) {\n    if (k.endsWith('-bin')) {\n      if (!(v instanceof Uint8Array) && !(v instanceof ArrayBuffer)) {\n        throw new Error(`${where}[\"${k}\"] must be binary (Uint8Array/ArrayBuffer)`);\n      }\n    } else if (typeof v !== 'string') {\n      throw new Error(`${where}[\"${k}\"] must be a string`);\n    }\n  }\n  return true;\n}","tryCatchPattern":null,"preventionTips":["Always construct metadata as a plain object literal, never a string or array","Stringify numeric/boolean values before putting them into metadata","Reserve -bin suffixes for keys whose values come from typed arrays"],"tags":["grpc","metadata","type-error","params"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}