{"record":{"id":"6a0eaeab9ef66fd3","repo":"grafana/k6","slug":"markedasfailed-exit-code-107","errorCode":"MarkedAsFailed (exit code 107)","errorMessage":"test run was marked as failed","messagePattern":"test run was marked as failed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/run.go","lineNumber":488,"sourceCode":"\tif err != nil {\n\t\terr = common.UnwrapSobekInterruptedError(err)\n\t\tlogger.WithError(err).Debug(\"Test finished with an error\")\n\t\tsetExecutionResult(executionState, err)\n\t\treturn err\n\t}\n\n\t// Warn if no iterations could be completed.\n\tif executionState.GetFullIterationCount() == 0 {\n\t\tlogger.Warn(\"No script iterations fully finished, consider making the test duration longer\")\n\t}\n\n\t// The execution module enables users to mark a test as failed, while letting the test\n\t// execution complete. As such, we check the test status here, after the test run has finished, and\n\t// ensure we return an error indicating that the test run was marked as failed, and the proper\n\t// exit code is used.\n\tif testRunState.TestStatus.Failed() {\n\t\terr = errext.WithExitCodeIfNone(\n\t\t\tfmt.Errorf(\"test run was marked as failed\"),\n\t\t\texitcodes.MarkedAsFailed,\n\t\t)\n\t\tsetExecutionResult(executionState, err)\n\t\treturn err\n\t}\n\n\tlogger.Debug(\"Test finished cleanly\")\n\tsetExecutionResult(executionState, nil)\n\n\treturn nil\n}\n\nfunc setExecutionResult(executionState *lib.ExecutionState, err error) {\n\texitCode := 0\n\tif err != nil {\n\t\texitCode = -1\n\t\tif ecerr, ok := errors.AsType[errext.HasExitCode](err); ok {\n\t\t\texitCode = int(ecerr.ExitCode())","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/cmd/run.go#L470-L506","documentation":"k6 lets a test mark itself as failed at runtime (e.g. via test.fail() or the execution module) while still letting execution complete. After the run finishes, k6 checks the test status and returns this error with exit code 107 so CI systems see the failure.","triggerScenarios":"Test script calls test.fail() (or sets the test status to failed via the execution module), and the run completes without any other fatal error.","commonSituations":"Intentional conditional failures (test.fail(condition, msg)) in data-driven tests; CI pipelines breaking because exit code 107 wasn't expected; scripts that call test.fail() unconditionally by mistake.","solutions":["Inspect the script's test.fail() calls: fix the underlying assertion/logic that triggers the failure, or remove the call if it was added by mistake.","If failing is intentional, accept exit code 107 in CI, or gate test.fail() behind a condition that only fires for genuine regressions.","Use checks/thresholds configuration (thresholds.abortOnFail) as an alternative if the goal is fail-fast behavior."],"exampleFix":"// before\ntest.fail();\n// after\ntest.fail(response.status !== 200, 'expected 200, got ' + response.status);","handlingStrategy":"try-catch","validationCode":"// In CI, expect exit code 107 when intentional failure is used:\n// k6 run script.js; code=$?; if [ $code -ne 0 ] && [ $code -ne 107 ]; then exit $code; fi","typeGuard":null,"tryCatchPattern":"// In Go code driving k6:\nvar ec errext.HasExitCode\nif errors.As(err, &ec) && ec.ExitCode() == exitcodes.MarkedAsFailed {\n  // test intentionally marked failed; handle distinctly\n}","preventionTips":["Audit test.fail() calls so they are gated on real conditions.","Document exit code 107 in CI configs so intentional failures are handled.","Prefer thresholds/checks with abortOnFail for fail-fast semantics."],"tags":["k6","exit-code","ci","test-status"],"backgroundTag":"invalid-state-transition","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-09-20T22:01:45.163Z","contentChangedAt":"2026-09-20T22:01:45.163Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}