{"record":{"id":"4f13f84b84ea0817","repo":"grafana/k6","slug":"testrunid-of-the-test-is-required","errorCode":null,"errorMessage":"TestRunID of the test is required","messagePattern":"TestRunID of the test is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"output/cloud/expv2/metrics_client.go","lineNumber":45,"sourceCode":"\thttpClient metricsHTTPClient\n\turl        string\n}\n\n// deriveMetricsURL builds the v2 metrics-ingestion URL from the Cloud\n// service base URL, used when no explicit push URL was provided.\n//\n// The cloudapi.Client works across different versions of the API: test\n// lifecycle management is under /v1 while metrics ingestion is /v2.\n// The client has /v1 hard-coded, so we trim it and replace with /v2.\n// A versioned client would be better but it would require a breaking\n// change, and other services (e.g. k6-operator) depend on it, so we want\n// to stabilize the API first.\nfunc deriveMetricsURL(baseURL, testRunID string) (string, error) {\n\tif !strings.HasSuffix(baseURL, \"/v1\") {\n\t\treturn \"\", errors.New(\"a /v1 suffix is expected in the Cloud service's BaseURL path\")\n\t}\n\tif testRunID == \"\" {\n\t\treturn \"\", errors.New(\"TestRunID of the test is required\")\n\t}\n\treturn strings.TrimSuffix(baseURL, \"/v1\") + \"/v2/metrics/\" + testRunID, nil\n}\n\n// newMetricsClientWithURL builds a metricsClient with an explicit push URL.\n// It is the single metricsClient constructor: callers that need the\n// host-derived URL compute it via deriveMetricsURL first.\nfunc newMetricsClientWithURL(c metricsHTTPClient, url string) (*metricsClient, error) {\n\tif url == \"\" {\n\t\treturn nil, errors.New(\"metrics push URL is required\")\n\t}\n\treturn &metricsClient{\n\t\thttpClient: c,\n\t\turl:        url,\n\t}, nil\n}\n\n// Push the provided metrics for the given test run ID. The context cancels the","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/output/cloud/expv2/metrics_client.go#L27-L63","documentation":"Returned by deriveMetricsURL (output/cloud/expv2/metrics_client.go:44-46) when the test run ID is an empty string. The v2 ingestion URL embeds the run ID as its final path segment (.../v2/metrics/<testRunID>, line 47), so an empty ID would produce a malformed URL and metrics would go nowhere; the guard fails fast instead. Hit from Output.Start (output.go:134) in the legacy derivation path (when no explicit metrics client/URL were injected), wrapped as 'failed to derive the metrics push URL: TestRunID of the test is required'.","triggerScenarios":"The expv2 output starting without a test run reference: e.g. providing K6_CLOUD_METRICS_PUSH_URL + K6_CLOUD_TEST_RUN_TOKEN but omitting K6_CLOUDRUN_TEST_RUN_ID (internal/output/cloud/output.go reads testRunID from that key), or programmatic use of the output where SetTestRunID-equivalent setup was skipped before Start().","commonSituations":"Direct-to-ingestion setups (token mode) where the run is provisioned externally but the ID env var is missing from CI; wrappers (k6-operator, custom harnesses) that construct the cloud output without wiring the run ID.","solutions":["Set K6_CLOUDRUN_TEST_RUN_ID to the externally provisioned test run reference when pushing to a pre-created run","Or use the normal k6 cloud / token flow where the client creates the test run and Start() receives a non-empty ID"],"exampleFix":"# before\nK6_CLOUD_METRICS_PUSH_URL=https://ingest.example/v2/metrics \\\nK6_CLOUD_TEST_RUN_TOKEN=*** k6 run -o cloud script.js\n\n# after\nK6_CLOUD_METRICS_PUSH_URL=https://ingest.example/v2/metrics \\\nK6_CLOUD_TEST_RUN_TOKEN=*** \\\nK6_CLOUDRUN_TEST_RUN_ID=12345 k6 run -o cloud script.js","handlingStrategy":"validation","validationCode":"# shell: token-ingestion mode requires a run ID\nif [ -n \"$K6_CLOUD_METRICS_PUSH_URL\" ] && [ -z \"$K6_CLOUDRUN_TEST_RUN_ID\" ]; then\n  echo \"K6_CLOUDRUN_TEST_RUN_ID is required when pushing to a pre-provisioned run\"; exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When provisioning test runs externally, export K6_CLOUDRUN_TEST_RUN_ID in the same CI step that sets the push URL/token","Prefer the standard k6 cloud / token flow where the run is created for you, so the ID is never empty"],"tags":["cloud-output","testrun","config","k6"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}