{"record":{"id":"7bec815ad628969b","repo":"grafana/k6","slug":"providing-service-version-is-required","errorCode":null,"errorMessage":"providing service version is required","messagePattern":"providing service version is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/output/opentelemetry/config.go","lineNumber":215,"sourceCode":"\t\tcfg.HTTPUsername = v.HTTPUsername\n\t}\n\n\tif v.HTTPPassword.Valid {\n\t\tcfg.HTTPPassword = v.HTTPPassword\n\t}\n\n\treturn cfg\n}\n\n// Validate validates the config\nfunc (cfg Config) Validate() error {\n\tif cfg.ServiceName.String == \"\" {\n\t\treturn errors.New(\"providing service name is required\")\n\t}\n\t// TODO: it's not actually required, but we should probably have a default\n\t// check if it works without it\n\tif cfg.ServiceVersion.String == \"\" {\n\t\treturn errors.New(\"providing service version is required\")\n\t}\n\tif err := cfg.validateExporterProtocol(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (cfg Config) validateExporterProtocol() error {\n\tif cfg.ExporterProtocol.String != \"\" {\n\t\tif cfg.ExporterProtocol.String != grpcExporterProtocol && cfg.ExporterProtocol.String != httpExporterProtocol {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"unsupported exporter protocol %q, only %q and %q are supported\",\n\t\t\t\tcfg.ExporterProtocol.String,\n\t\t\t\tgrpcExporterProtocol,\n\t\t\t\thttpExporterProtocol,\n\t\t\t)\n\t\t}\n\t\tswitch cfg.ExporterProtocol.String {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/output/opentelemetry/config.go#L197-L233","documentation":"The OpenTelemetry metrics output requires a service version for the exported resource. k6 defaults it to the k6 build version, but Validate() rejects the config when ServiceVersion.String is empty — typically because K6_OTEL_SERVICE_VERSION or the JSON output config overrode the default with an empty string. The code even carries a TODO noting the requirement is arguably artificial, but it is enforced.","triggerScenarios":"export K6_OTEL_SERVICE_VERSION= (defined but empty); an output config JSON with \"serviceVersion\": \"\".","commonSituations":"CI placeholder variables left empty; pipelines that set the version only for release builds and leave it blank in dev jobs.","solutions":["Set a real value, e.g. export K6_OTEL_SERVICE_VERSION=1.4.2","Remove the empty K6_OTEL_SERVICE_VERSION from the environment so the k6 version default applies","Populate the variable from the build metadata you already have (git describe, package version) in CI"],"exampleFix":"# before\nexport K6_OTEL_SERVICE_VERSION=\nk6 run -o opentelemetry script.js\n# after\nexport K6_OTEL_SERVICE_VERSION=$(git describe --tags --always)\nk6 run -o opentelemetry script.js","handlingStrategy":"validation","validationCode":"// Shell: treat empty as unset (falls back to k6's version)\n[ -z \"${K6_OTEL_SERVICE_VERSION:-}\" ] && unset K6_OTEL_SERVICE_VERSION\nexport K6_OTEL_SERVICE_VERSION=\"${K6_OTEL_SERVICE_VERSION:-$(git describe --tags --always 2>/dev/null || echo dev)}\"\nk6 run -o opentelemetry script.js","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Populate the version from build metadata you already produce (git describe, package version)","Never export an empty K6_OTEL_SERVICE_VERSION placeholder","Add a pre-flight env check in CI for all required OTel variables"],"tags":["opentelemetry","observability","configuration","environment-variables","k6"],"backgroundTag":"empty-env-var-override","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}