{"record":{"id":"b1ca338afd1cf4f0","repo":"grafana/k6","slug":"failed-to-register-grpc-module-metrics-w","errorCode":null,"errorMessage":"failed to register GRPC module metrics: %w","messagePattern":"failed to register GRPC module metrics: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/grpc.go","lineNumber":47,"sourceCode":"\t}\n)\n\nvar (\n\t_ modules.Module   = &RootModule{}\n\t_ modules.Instance = &ModuleInstance{}\n)\n\n// New returns a pointer to a new RootModule instance.\nfunc New() *RootModule {\n\treturn &RootModule{}\n}\n\n// NewModuleInstance implements the modules.Module interface to return\n// a new instance for each VU.\nfunc (r *RootModule) NewModuleInstance(vu modules.VU) modules.Instance {\n\tmetrics, err := registerMetrics(vu.InitEnv().Registry)\n\tif err != nil {\n\t\tcommon.Throw(vu.Runtime(), fmt.Errorf(\"failed to register GRPC module metrics: %w\", err))\n\t}\n\n\tmi := &ModuleInstance{\n\t\tvu:      vu,\n\t\texports: make(map[string]any),\n\t\tmetrics: metrics,\n\t}\n\n\tmi.exports[\"Client\"] = mi.NewClient\n\tmi.defineConstants()\n\tmi.exports[\"Stream\"] = mi.stream\n\n\treturn mi\n}\n\n// NewClient is the JS constructor for the grpc Client.\nfunc (mi *ModuleInstance) NewClient(_ sobek.ConstructorCall) *sobek.Object {\n\trt := mi.vu.Runtime()","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/grpc.go#L29-L65","documentation":"k6 registers three Counter metrics for the gRPC module (grpc_streams, grpc_streams_msgs_sent, grpc_streams_msgs_received) on the test-wide metric registry every time a VU instantiates 'k6/grpc' (internal/js/modules/k6/grpc/metrics.go:17-27). registry.NewMetric fails when one of these names already exists with a different metric type, and NewModuleInstance converts that failure into this thrown error during the init stage, before any traffic runs.","triggerScenarios":"A script that imports 'k6/grpc' and also creates its own metric with a reserved name and a non-Counter type, e.g. new Trend('grpc_streams') or new Rate('grpc_streams_msgs_sent') from 'k6/metrics' (same-name Counters are reused, other types collide). Also possible in xk6/embedded builds where another extension registers a colliding name, or when the VU's InitEnv registry is not initialized (k6 internal defect).","commonSituations":"Teams that named their own gRPC summary metrics before k6 reserved these names; k6 upgrades that introduced stream metrics; multi-extension builds with duplicate registrations.","solutions":["Rename the colliding custom metric: grep the script and shared helpers for grpc_streams, grpc_streams_msgs_sent, grpc_streams_msgs_received and change any non-Counter metric using those names","If you need those exact names, keep the type Counter so registry.NewMetric reuses the existing metric instead of erroring","If no custom metric collides, reproduce with a minimal script that only does `import grpc from 'k6/grpc'` and report it as a k6 bug with your k6 version"],"exampleFix":"// before\nimport { Trend } from 'k6/metrics';\nimport grpc from 'k6/grpc';\nconst streams = new Trend('grpc_streams');\n\n// after\nimport { Trend } from 'k6/metrics';\nimport grpc from 'k6/grpc';\nconst streams = new Trend('my_grpc_streams');","handlingStrategy":"validation","validationCode":"// Reserved by k6's gRPC module: only Counters may use these names\nconst GRPC_RESERVED = ['grpc_streams', 'grpc_streams_msgs_sent', 'grpc_streams_msgs_received'];\n// Before shipping, grep every new Counter/Trend/Gauge/Rate name against this list;\n// any same-name non-Counter metric aborts script init.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never create custom metrics named grpc_streams, grpc_streams_msgs_sent or grpc_streams_msgs_received unless they are Counters","Prefix team metric names with a project prefix to avoid reserved k6 names","After upgrading k6, run a smoke script that imports k6/grpc to catch registration errors before real test runs"],"tags":["grpc","metrics","init","name-collision"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}