{"record":{"id":"91f7d82ad116ed9b","repo":"grafana/k6","slug":"error-for-stage-d-w","errorCode":null,"errorMessage":"error for stage %d: %w","messagePattern":"error for stage (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/options.go","lineNumber":114,"sourceCode":"\t\tNoConnectionReuse:       getNullBool(flags, \"no-connection-reuse\"),\n\t\tNoVUConnectionReuse:     getNullBool(flags, \"no-vu-connection-reuse\"),\n\t\tMinIterationDuration:    getNullDuration(flags, \"min-iteration-duration\"),\n\t\tThrow:                   getNullBool(flags, \"throw\"),\n\t\tDiscardResponseBodies:   getNullBool(flags, \"discard-response-bodies\"),\n\t\tMetricSamplesBufferSize: null.NewInt(1000, false),\n\t}\n\n\t// Using Changed() because GetStringSlice() doesn't differentiate between empty and no value\n\tif flags.Changed(\"stage\") {\n\t\tstageStrings, err := flags.GetStringSlice(\"stage\")\n\t\tif err != nil {\n\t\t\treturn opts, err\n\t\t}\n\t\topts.Stages = []lib.Stage{}\n\t\tfor i, s := range stageStrings {\n\t\t\tvar stage lib.Stage\n\t\t\tif err := stage.UnmarshalText([]byte(s)); err != nil {\n\t\t\t\treturn opts, fmt.Errorf(\"error for stage %d: %w\", i, err)\n\t\t\t}\n\t\t\tif !stage.Duration.Valid {\n\t\t\t\treturn opts, fmt.Errorf(\"stage %d doesn't have a specified duration\", i)\n\t\t\t}\n\t\t\topts.Stages = append(opts.Stages, stage)\n\t\t}\n\t}\n\n\tif flags.Changed(\"execution-segment\") {\n\t\texecutionSegmentStr, err := flags.GetString(\"execution-segment\")\n\t\tif err != nil {\n\t\t\treturn opts, err\n\t\t}\n\t\tsegment := new(lib.ExecutionSegment)\n\t\terr = segment.UnmarshalText([]byte(executionSegmentStr))\n\t\tif err != nil {\n\t\t\treturn opts, err\n\t\t}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cmd/options.go#L96-L132","documentation":"Emitted while parsing the repeatable --stage flag (e.g. `k6 run --stage 1m:10,...`). Each stage string is split on ':' and decoded by lib.Stage.UnmarshalText: the left side must be a Go duration (time.ParseDuration) and the right side a plain integer VU target. Any duration without a unit, non-numeric target, or extra malformed text fails with this per-index wrap, where %d is the position (0-based) in the --stage list.","triggerScenarios":"`--stage 10:5` (duration '10' has no unit, needs '10s'), `--stage 1m:five`, `--stage 1m:10:extra`, or a stage copied from JSON config syntax (`{\"duration\":\"1m\",\"target\":10}`) pasted verbatim into the flag.","commonSituations":"Assuming seconds-by-default like some other tools; converting ramping-vus JSON options into CLI flags by hand; shell loops concatenating stage strings with stray separators.","solutions":["Use Go duration syntax on the left of ':' — always with a unit: `--stage 30s:10 --stage 1m:5 --stage 10s:0`","Keep the target side a bare integer (VUs), no quotes/decimals","Count from 0: the index in the message points at the exact --stage occurrence to fix","Prefer a JSON/YAML options block (stages: [...]) when the ramp gets complex, instead of long flag chains"],"exampleFix":"# before\nk6 run --stage 20:10 --stage 1m:5 script.js\n# error: error for stage 0: time: missing unit in duration \"20\"\n\n# after\nk6 run --stage 20s:10 --stage 1m:5 script.js","handlingStrategy":"validation","validationCode":"# Validate --stage strings: '<duration-with-unit>:<integer>' before running\nfor s in \"${stages[@]}\"; do\n  [[ \"$s\" =~ ^[0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h):[0-9]+$ ]] \\\n    || { echo \"bad stage '$s' (want e.g. 30s:10)\"; exit 1; }\ndone\nk6 run ${stages[@]/#/--stage } script.js","typeGuard":"function isValidStageFlag(s) {\n  return /^[0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h):[0-9]+$/.test(s.trim());\n}","tryCatchPattern":null,"preventionTips":["Always write durations with explicit units (30s, 1m) — k6 never assumes seconds","Keep targets as plain integers; no decimals, no quotes","For more than ~3 stages, move them into the script's options.stages instead of CLI flags"],"tags":["cli","options","stages","duration","parsing"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}