grafana/k6 · error
MarkedAsFailed (exit code 107)
MarkedAsFailed (exit code 107)
Error message
test run was marked as failed
What it means
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.
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.
Example fix
// before test.fail(); // after test.fail(response.status !== 200, 'expected 200, got ' + response.status);
Defensive patterns
Strategy: try-catch
Validate before calling
// In CI, expect exit code 107 when intentional failure is used: // k6 run script.js; code=$?; if [ $code -ne 0 ] && [ $code -ne 107 ]; then exit $code; fi
Try / catch
// In Go code driving k6:
var ec errext.HasExitCode
if errors.As(err, &ec) && ec.ExitCode() == exitcodes.MarkedAsFailed {
// test intentionally marked failed; handle distinctly
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-20).
Data as JSON: /api/errors/6a0eaeab9ef66fd3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cmd/run.go:488
if err != nil {
err = common.UnwrapSobekInterruptedError(err)
logger.WithError(err).Debug("Test finished with an error")
setExecutionResult(executionState, err)
return err
}
// Warn if no iterations could be completed.
if executionState.GetFullIterationCount() == 0 {
logger.Warn("No script iterations fully finished, consider making the test duration longer")
}
// The execution module enables users to mark a test as failed, while letting the test
// execution complete. As such, we check the test status here, after the test run has finished, and
// ensure we return an error indicating that the test run was marked as failed, and the proper
// exit code is used.
if testRunState.TestStatus.Failed() {
err = errext.WithExitCodeIfNone(
fmt.Errorf("test run was marked as failed"),
exitcodes.MarkedAsFailed,
)
setExecutionResult(executionState, err)
return err
}
logger.Debug("Test finished cleanly")
setExecutionResult(executionState, nil)
return nil
}
func setExecutionResult(executionState *lib.ExecutionState, err error) {
exitCode := 0
if err != nil {
exitCode = -1
if ecerr, ok := errors.AsType[errext.HasExitCode](err); ok {
exitCode = int(ecerr.ExitCode())View on GitHub (pinned to 3fcf5388d7)