{"record":{"id":"3b6c5cefa3e685fc","repo":"grafana/k6","slug":"97","errorCode":"97","errorMessage":"The test has failed","messagePattern":"The test has failed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/cloud.go","lineNumber":419,"sourceCode":"\n\t// Stop progress rendering before printing final status to avoid ghost bars.\n\tprogressCancel()\n\tprogressBarWG.Wait()\n\n\tif testProgress == nil {\n\t\t//nolint:staticcheck\n\t\treturn errext.WithExitCodeIfNone(errors.New(\"Test progress error\"), exitcodes.CloudFailedToGetProgress)\n\t}\n\n\tprintCloudTestStatus(gs, testProgress.FormatStatus())\n\n\tif testProgress.ThresholdsFailed() {\n\t\t//nolint:staticcheck\n\t\treturn errext.WithExitCodeIfNone(errors.New(\"Thresholds have been crossed\"), exitcodes.ThresholdsHaveFailed)\n\t}\n\tif testProgress.TestFailed() {\n\t\t//nolint:staticcheck\n\t\treturn errext.WithExitCodeIfNone(errors.New(\"The test has failed\"), exitcodes.CloudTestRunFailed)\n\t}\n\n\treturn nil\n}\n\nfunc printCloudTestStatus(gs *state.GlobalState, status string) {\n\tif !gs.Flags.Quiet {\n\t\tvalueColor := getColor(gs.Flags.NoColor || !gs.Stdout.IsTTY, color.FgCyan)\n\t\tprintToStdout(gs, fmt.Sprintf(\n\t\t\t\"     test status: %s\\n\", valueColor.Sprint(status),\n\t\t))\n\t} else {\n\t\tgs.Logger.WithField(\"run_status\", status).Debug(\"Test finished\")\n\t}\n}\n\n// cloudCmdFlagSet returns the flag set used by the cloud run command,\n// binding the --exit-on-running and --show-logs flags to the provided values.","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/grafana/k6/blob/94169daab29df52c1ed2ee0549657a577666b855/internal/cmd/cloud.go#L401-L437","documentation":"Returned at the end of `k6 cloud run` when the finished cloud run's result status is 'failed' but thresholds did not cross (that case gets exit 99). k6 exits with code 97 (exitcodes.CloudTestRunFailed), meaning the run itself failed cloud-side or in-script — e.g. script exceptions during execution, an aborted run, or infrastructure errors reported by Grafana Cloud.","triggerScenarios":"The run finishes with testProgress.TestFailed() true: script errors thrown during iterations in the cloud, the run was aborted from the UI (after the CLI already latched a failed result), or the cloud marked the run failed due to internal errors. Distinct from threshold failures (99) and monitoring loss (98).","commonSituations":"Unhandled JS exceptions that only trigger under cloud data/distribution; aborting runs from the Grafana UI; cloud-side infrastructure incidents; scripts importing local files/bundled modules that fail in the cloud environment.","solutions":["Open the run details URL printed by k6 — the failure reason is shown in the Grafana Cloud UI","Check the cloud logs pane (or rerun with --show-logs) for script exceptions during the run","If the run was aborted intentionally from the UI, the exit 97 can be ignored","Fix the script errors, verify the archive works locally (`k6 run archive.tar`), then rerun","If Grafana Cloud reports an internal error, retry after the incident resolves"],"exampleFix":"// common cause: an exception that only some VUs hit in the cloud\n// before\nimport http from 'k6/http';\nexport default function () {\n  const body = http.get('https://example.com/api').json(); // throws if body isn't JSON\n  console.log(body.field.length); // throws if field is undefined\n}\n\n// after\nimport http from 'k6/http';\nimport check from 'k6/check';\nexport default function () {\n  const res = http.get('https://example.com/api');\n  check(res, { 'json body': (r) => r.status === 200 && r.json('field') !== null });\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"k6 cloud run script.js\ncode=$?\ncase $code in\n  97) echo \"cloud run failed - inspect the run URL and cloud logs\" ;;\n  98) echo \"progress monitoring lost\" ;;\n  99) echo \"thresholds crossed\" ;;\nesac\nexit $code","preventionTips":["Guard script code that parses responses (check status/json before dereferencing fields)","Verify the archive runs locally (`k6 run archive.tar`) before sending it to the cloud","Stream cloud logs with --show-logs (or K6_SHOW_CLOUD_LOGS=true) so run-failure causes are captured"],"tags":["k6","cloud","test-failed","exit-code-97","grafana-cloud"],"backgroundTag":"test-run-failed","analyzedSha":"94169daab29df52c1ed2ee0549657a577666b855","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}