{"record":{"id":"7fa6690109cdd473","repo":"grafana/k6","slug":"the-open-function-is-only-available-in-the-init","errorCode":null,"errorMessage":"the \"open\" function is only available in the init stage (i.e. the global scope), see https://grafana.com/docs/k6/latest/using-k6/test-lifecycle/ for more information","messagePattern":"the \"open\" function is only available in the init stage \\(i\\.e\\. the global scope\\), see https://grafana\\.com/docs/k6/latest/using-k6/test-lifecycle/ for more information","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/bundle.go","lineNumber":478,"sourceCode":"\nfunc (b *Bundle) setInitGlobals(rt *sobek.Runtime, vu *moduleVUImpl, modSys *modules.ModuleSystem) {\n\tmustSet := func(k string, v any) {\n\t\tif err := rt.Set(k, v); err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed to set '%s' global object: %w\", k, err))\n\t\t}\n\t}\n\n\timpl := requireImpl{\n\t\tinInitContext: func() bool { return vu.state == nil },\n\t\tmodSys:        modSys,\n\t}\n\n\tmustSet(\"require\", impl.require)\n\n\tmustSet(\"open\", func(filename string, args ...string) (sobek.Value, error) {\n\t\t// TODO fix in stack traces\n\t\tif vu.state != nil {\n\t\t\treturn nil, fmt.Errorf(cantBeUsedOutsideInitContextMsg, \"open\")\n\t\t}\n\n\t\tif filename == \"\" {\n\t\t\treturn nil, errors.New(\"open() can't be used with an empty filename\")\n\t\t}\n\t\t// This uses the pwd from the requireImpl\n\t\tpwd, err := modSys.CurrentlyRequiredModule()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !strings.HasPrefix(filename, \"file://\") && !filepath.IsAbs(filename) {\n\t\t\totherPath, shouldWarn := modSys.ShouldWarnOnParentDirNotMatchingCurrentModuleParentDir(vu, pwd)\n\t\t\tlogger := b.preInitState.Logger\n\t\t\tif shouldWarn {\n\t\t\t\tlogger.Warningf(\"open() was used and is currently relative to '%s', but in the future \"+\n\t\t\t\t\t\"it will be aligned with how `require` and imports work and will be relative to '%s'. This means \"+\n\t\t\t\t\t\"that in the future open will open relative path relative to the module/file it is written in. \"+\n\t\t\t\t\t\"You can future proof this by using `import.meta.resolve()` to get relative paths to the file it \"+","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/bundle.go#L460-L496","documentation":"Like require(), open() is restricted to the init stage: the closure installed by setInitGlobals checks vu.state and throws when open() runs where a VU state exists (default function, setup, teardown, handleSummary). Files must be read during initialization because k6 caches their contents and distributes them to every VU before the test starts.","triggerScenarios":"Calling open('data.json') inside export default function, setup(), teardown(), or helpers invoked from them; passing open as a callback; attempting per-iteration file reads.","commonSituations":"Data-driven tests trying to read fixtures per iteration; porting Node.js scripts that call fs.readFile anywhere; moving file reads inside functions during refactoring.","solutions":["Open the file at the top level and capture the result in a const, then use that const inside the default function","For large shared datasets, load the content into a SharedArray at init","Remember setup()/teardown() are not the init stage either - open() is unavailable there"],"exampleFix":"// before: open() inside the default function\nexport default function () {\n  const data = JSON.parse(open('./users.json'));\n}\n\n// after: read at init, share via SharedArray\nimport { SharedArray } from 'k6/data';\nconst users = new SharedArray('users', () => JSON.parse(open('./users.json')).users);\nexport default function () {\n  const user = users[__ITER % users.length];\n}","handlingStrategy":"validation","validationCode":"# heuristic static check: open() on an indented line runs in the VU stage\ngrep -nP '^[[:space:]]+.*\\bopen\\(' script.js && \\\n  { echo 'open() found outside top-level init code'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Read all files at the top level into consts; reference those consts inside functions","Use SharedArray for datasets shared across VUs","Remember setup()/teardown()/handleSummary run with a VU state - no open() there"],"tags":["lifecycle","init-stage","open","files"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}