{"record":{"id":"0e0ca1b2b53d3331","repo":"grafana/k6","slug":"failed-to-create-request-metadata-request-w","errorCode":null,"errorMessage":"failed to create request metadata request: %w","messagePattern":"failed to create request metadata request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloudapi/insights/mappers.go","lineNumber":18,"sourceCode":"package insights\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"go.k6.io/k6/v2/internal/cloudapi/insights/proto/v1/ingester\"\n\t\"go.k6.io/k6/v2/internal/cloudapi/insights/proto/v1/k6\"\n)\n\nfunc newBatchCreateRequestMetadatasRequest(\n\trequestMetadatas RequestMetadatas,\n) (*ingester.BatchCreateRequestMetadatasRequest, error) {\n\treqs := make([]*ingester.CreateRequestMetadataRequest, 0, len(requestMetadatas))\n\tfor _, rm := range requestMetadatas {\n\t\treq, err := newCreateRequestMetadataRequest(rm)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create request metadata request: %w\", err)\n\t\t}\n\n\t\treqs = append(reqs, req)\n\t}\n\n\treturn &ingester.BatchCreateRequestMetadatasRequest{\n\t\tRequests: reqs,\n\t}, nil\n}\n\nfunc newCreateRequestMetadataRequest(requestMetadata RequestMetadata) (*ingester.CreateRequestMetadataRequest, error) {\n\trm := &k6.RequestMetadata{\n\t\tTraceID:           requestMetadata.TraceID,\n\t\tStartTimeUnixNano: requestMetadata.Start.UnixNano(),\n\t\tEndTimeUnixNano:   requestMetadata.End.UnixNano(),\n\t\tTestRunLabels: &k6.TestRunLabels{\n\t\t\tID:       requestMetadata.TestRunLabels.ID,\n\t\t\tScenario: requestMetadata.TestRunLabels.Scenario,","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/cloudapi/insights/mappers.go#L1-L36","documentation":"Returned by newBatchCreateRequestMetadatasRequest in internal/cloudapi/insights/mappers.go:18 when any single entry of a RequestMetadatas batch fails to map into the protobuf ingester type. It is a pure wrapper: the %w chain always ends in the only real error source in this file, setProtocolLabels' 'unknown protocol labels type' (mappers.go:63), because newCreateRequestMetadataRequest itself cannot otherwise fail. The whole batch is abandoned on the first bad entry.","triggerScenarios":"Calling newBatchCreateRequestMetadatasRequest (or the insights push path above it) with a batch in which at least one RequestMetadata has ProtocolLabels that is nil or any type other than ProtocolHTTPLabels — the switch in setProtocolLabels (mappers.go:51-64) has only a ProtocolHTTPLabels case plus a default that errors, per the 'TODO(other-proto-support)' comment.","commonSituations":"Extending k6 insights to a new protocol (gRPC, WebSocket) and passing its label struct before adding a case in setProtocolLabels; constructing RequestMetadata programmatically (xk6 extension or tests) and leaving ProtocolLabels unset; a nil ProtocolLabels sneaking in for non-HTTP requests during a mixed-protocol test run.","solutions":["Unwrap the error chain and confirm the root cause is 'unknown protocol labels type'; identify which batch entry carries the unsupported labels type.","If your batch can contain non-HTTP entries, filter them out (or skip nil ProtocolLabels) before calling the batch mapper — only ProtocolHTTPLabels is supported today.","If you are adding a new protocol, extend the type switch in setProtocolLabels (mappers.go:53) with a case mapping your labels to the corresponding k6.RequestMetadata_* protobuf oneof member, and regenerate proto types if needed.","Re-run and verify the batch maps fully by checking that the error no longer surfaces in the insights ingest path."],"exampleFix":"// before (mappers.go setProtocolLabels): only HTTP is mapped\n\tswitch l := labels.(type) {\n\tcase ProtocolHTTPLabels:\n\t\trm.ProtocolLabels = &k6.RequestMetadata_HTTPLabels{...}\n\tdefault:\n\t\treturn errors.New(\"unknown protocol labels type\")\n\t}\n\n// after: also tolerate nil / map a new protocol\n\tswitch l := labels.(type) {\n\tcase ProtocolHTTPLabels:\n\t\trm.ProtocolLabels = &k6.RequestMetadata_HTTPLabels{...}\n\tcase ProtocolGRPCLabels: // new protocol support\n\t\trm.ProtocolLabels = &k6.RequestMetadata_GRPCLabels{...}\n\tcase nil:\n\t\treturn nil // no protocol-specific labels\n\tdefault:\n\t\treturn errors.New(\"unknown protocol labels type\")\n\t}","handlingStrategy":"validation","validationCode":"// Filter a batch to entries the insights mapper can handle before calling it.\nfunc supportedForInsights(rms insights.RequestMetadatas) insights.RequestMetadatas {\n\tout := make(insights.RequestMetadatas, 0, len(rms))\n\tfor _, rm := range rms {\n\t\tif rm.ProtocolLabels == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := rm.ProtocolLabels.(insights.ProtocolHTTPLabels); !ok {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, rm)\n\t}\n\treturn out\n}","typeGuard":"func isSupportedProtocolLabels(l insights.ProtocolLabels) bool {\n\t_, ok := l.(insights.ProtocolHTTPLabels)\n\treturn ok\n}","tryCatchPattern":"if _, err := insights.BuildBatchRequest(rms); err != nil {\n\tvar protoErr *insights.UnsupportedProtocolError // if introduced; else match on message\n\tif errors.As(err, &protoErr) || strings.Contains(err.Error(), \"unknown protocol labels type\") {\n\t\t// drop unsupported entries and rebuild, or skip insights for this batch\n\t}\n}","preventionTips":["Only route HTTP requests into the insights mapper until non-HTTP label support ships.","Never construct RequestMetadata with nil ProtocolLabels when it will be batched.","Pin extension protocol-label types to the k6 version whose mapper supports them."],"tags":["k6","insights","cloud","protobuf","type-switch","request-metadata"],"backgroundTag":"unsupported-protocol-type","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}