{"record":{"id":"23426caa98bb7373","repo":"grafana/k6","slug":"the-fromline-option-must-be-greater-than-or-equa","errorCode":null,"errorMessage":"the 'fromLine' option must be greater than or equal to 0; got %d","messagePattern":"the 'fromLine' option must be greater than or equal to 0; got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/experimental/csv/reader.go","lineNumber":149,"sourceCode":"// validateOptions validates the reader options and returns an error if any validation fails.\nfunc validateOptions(options options) error {\n\tvar (\n\t\tfromLineSet      = options.FromLine.Valid\n\t\ttoLineSet        = options.ToLine.Valid\n\t\tskipFirstLineSet = options.SkipFirstLine\n\t\tasObjectsEnabled = options.AsObjects.Valid && options.AsObjects.Bool\n\t)\n\n\tif asObjectsEnabled && skipFirstLineSet {\n\t\treturn fmt.Errorf(\"the 'header' option cannot be enabled when 'skipFirstLine' is true\")\n\t}\n\n\tif asObjectsEnabled && fromLineSet && options.FromLine.Int64 > 0 {\n\t\treturn fmt.Errorf(\"the 'header' option cannot be enabled when 'fromLine' is set to a value greater than 0\")\n\t}\n\n\tif fromLineSet && options.FromLine.Int64 < 0 {\n\t\treturn fmt.Errorf(\"the 'fromLine' option must be greater than or equal to 0; got %d\", options.FromLine.Int64)\n\t}\n\n\tif toLineSet && options.ToLine.Int64 < 0 {\n\t\treturn fmt.Errorf(\"the 'toLine' option must be greater than or equal to 0; got %d\", options.ToLine.Int64)\n\t}\n\n\tif fromLineSet && toLineSet && options.FromLine.Int64 >= options.ToLine.Int64 {\n\t\treturn fmt.Errorf(\n\t\t\t\"the 'fromLine' option must be less than the 'toLine' option; got 'fromLine': %d, 'toLine': %d\",\n\t\t\toptions.FromLine.Int64, options.ToLine.Int64,\n\t\t)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":131,"sourceCodeEnd":165,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/experimental/csv/reader.go#L131-L165","documentation":"validateOptions in the experimental CSV reader rejects a negative fromLine (internal/js/modules/k6/experimental/csv/reader.go:148). fromLine is a 0-based line index marking where reading starts; any value below 0 is a programming or configuration error, not an empty range. The offending value is included in the message.","triggerScenarios":"`new csv.Parser(file, { fromLine: -1 })` or `csv.parse(file, { fromLine: -5 })` - most often a computed index such as `lineNo - 1` evaluating negative when lineNo is 0.","commonSituations":"Off-by-one arithmetic on 1-based line numbers from external config or CSV headers; using -1 as a sentinel meaning 'from the beginning'; formulas that underflow when a selection is empty.","solutions":["Pass 0 (or omit fromLine) to start at the first line","Clamp computed indices with Math.max(0, n) before passing them","Convert internal sentinels to 0 or undefined before constructing the parser"],"exampleFix":"// before\nconst from = startLine - 1; // startLine = 0 -> -1\nconst parser = new csv.Parser(file, { fromLine: from });\n\n// after\nconst from = Math.max(0, startLine - 1);\nconst parser = new csv.Parser(file, { fromLine: from });","handlingStrategy":"validation","validationCode":"function clampFromLine(o) {\n  if (o.fromLine !== undefined && o.fromLine < 0) {\n    throw new Error(`fromLine must be >= 0, got ${o.fromLine}`);\n  }\n  return o;\n}\n// or silently normalize: o.fromLine = Math.max(0, o.fromLine ?? 0);","typeGuard":null,"tryCatchPattern":"try { new csv.Parser(file, opts); } catch (e) { if (/fromLine.*greater than or equal/.test(e.message)) { opts.fromLine = 0; /* retry once */ } throw e; }","preventionTips":["Never pass computed indices unchecked; clamp with Math.max(0, n)","Reserve -1 sentinels for your own code and convert to 0/undefined at the boundary"],"tags":["csv","k6","validation","off-by-one"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}