{"record":{"id":"e45e00aa6c2042a2","repo":"grafana/k6","slug":"metric-tags-w","errorCode":null,"errorMessage":"metric tags: %w","messagePattern":"metric tags: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/params.go","lineNumber":53,"sourceCode":"\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)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/params.go#L35-L71","documentation":"params.tags is applied with common.ApplyCustomUserTags (js/common/tags.go:15), which accepts only String, Boolean and Number values for each tag key. An object, array, null or other kind as a tag value returns 'invalid value for metric tag ...', surfaced by the gRPC module prefixed with 'metric tags: '.","triggerScenarios":"{ tags: { user: { id: 7 } } }; { tags: { roles: ['admin'] } }; { tags: { parent: null } }.","commonSituations":"Tagging with decoded JSON bodies or nested identity objects; shared tag-builders that sometimes emit undefined or structured values.","solutions":["Flatten nested values to strings before tagging","Use String()/Number()/Boolean() conversions for scalars","Join arrays manually, e.g. roles.join(',')"],"exampleFix":"// before\nclient.invoke(method, req, { tags: { user: userObj } });\n\n// after\nclient.invoke(method, req, { tags: { userId: String(userObj.id) } });","handlingStrategy":"validation","validationCode":"function isValidTagValue(v) {\n  const t = typeof v;\n  return t === 'string' || t === 'boolean' || t === 'number';\n}\nfunction assertTags(tags) {\n  if (tags == null) return;\n  for (const [k, v] of Object.entries(tags)) {\n    if (!isValidTagValue(v)) throw new Error(`tag '${k}' must be a string, boolean or number`);\n  }\n}\nassertTags(params.tags);\nclient.invoke(method, req, params);","typeGuard":"function isScalarTag(v) {\n  const t = typeof v;\n  return t === 'string' || t === 'boolean' || t === 'number';\n}","tryCatchPattern":null,"preventionTips":["Flatten objects and arrays to strings before using them as tags","Never spread parsed JSON or identity objects directly into tags","Use one shared tag-builder that enforces scalar values"],"tags":["grpc","tags","metrics","type-error"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}