{"record":{"id":"00312a5789d9d634","repo":"grafana/k6","slug":"csv-parser-constructor-must-be-called-in-the-init","errorCode":null,"errorMessage":"csv Parser constructor must be called in the init context","messagePattern":"csv Parser constructor must be called in the init context","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/experimental/csv/module.go","lineNumber":155,"sourceCode":"\t\t\tcallback(func() error {\n\t\t\t\treturn reject(rt.NewGoError(err))\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tcallback(func() error {\n\t\t\treturn resolve(fn())\n\t\t})\n\t}()\n\n\treturn promise, nil\n}\n\n// NewParser creates a new CSV parser instance.\nfunc (mi *ModuleInstance) NewParser(call sobek.ConstructorCall) *sobek.Object {\n\trt := mi.vu.Runtime()\n\n\tif mi.vu.State() != nil {\n\t\tcommon.Throw(rt, errors.New(\"csv Parser constructor must be called in the init context\"))\n\t}\n\n\tif len(call.Arguments) < 1 || sobek.IsUndefined(call.Argument(0)) {\n\t\tcommon.Throw(rt, fmt.Errorf(\"csv Parser constructor takes at least one non-nil source argument\"))\n\t}\n\n\tfileArg := call.Argument(0)\n\tif common.IsNullish(fileArg) {\n\t\tcommon.Throw(rt, fmt.Errorf(\"csv Parser constructor takes at least one non-nil source argument\"))\n\t}\n\n\t// 1. Make sure the Sobek object is a fs.File (Sobek operation)\n\tvar file fs.File\n\tif err := mi.vu.Runtime().ExportTo(fileArg, &file); err != nil {\n\t\tcommon.Throw(\n\t\t\tmi.vu.Runtime(),\n\t\t\tfmt.Errorf(\"first argument expected to be a fs.File instance, got %T instead\", call.Argument(0)),\n\t\t)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/experimental/csv/module.go#L137-L173","documentation":"The experimental CSV Parser reads and parses the entire file once during script initialization for performance. Its constructor therefore rejects instantiation when vu.State() is non-nil, i.e. when the constructor runs inside the VU (default function) context instead of the init context.","triggerScenarios":"Calling new csv.Parser(file) inside export default function() or any function invoked per iteration; constructing the Parser lazily inside a helper that runs during the test.","commonSituations":"Refactoring a script and moving setup code into the default function; creating a Parser per iteration to 'reset' it instead of seeking; wrapping construction in a factory called from the default function.","solutions":["Instantiate the Parser at the top level of the script (init context)","Open the fs file in the init context too, since fs.open() is init-only as well","If per-iteration reset is needed, use parser.seek(0, SeekMode.Start) or create one Parser and share it"],"exampleFix":"// before\nexport default function () {\n  const parser = new csv.Parser(file);\n  // ...\n}\n\n// after\nconst parser = new csv.Parser(file);\nexport default function () {\n  // use parser here\n}","handlingStrategy":"validation","validationCode":"// Structural check: construction must sit at module top level.\n// Cheap runtime guard for factory wrappers:\nfunction makeParser(file) {\n  if (typeof (globalThis).Symbol === 'undefined') { /* init context heuristics */ }\n  return new csv.Parser(file);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the fs.open() and new csv.Parser() pair together at the top of the script file","Do not wrap Parser construction in per-iteration factories; seek back to 0 to restart reading","In code review, flag any csv.Parser occurrence inside export default"],"tags":["csv","init-context","experimental","parser"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}