{"record":{"id":"a36f80076b43a890","repo":"grafana/k6","slug":"the-require-function-is-only-available-in-the-in","errorCode":null,"errorMessage":"the \"require\" 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 \"require\" 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":456,"sourceCode":"\t\t\t\tglobalThis = newGlobal\n\t\t\t}),\n\t\t\tsobek.FLAG_TRUE, sobek.FLAG_TRUE)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// this exists only to make the check in the init context.\ntype requireImpl struct {\n\tinInitContext func() bool\n\tmodSys        *modules.ModuleSystem\n}\n\nfunc (r *requireImpl) require(specifier string) (*sobek.Object, error) {\n\tif !r.inInitContext() {\n\t\treturn nil, fmt.Errorf(cantBeUsedOutsideInitContextMsg, \"require\")\n\t}\n\treturn r.modSys.Require(specifier)\n}\n\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","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/bundle.go#L438-L474","documentation":"k6 scripts run in two stages: the init stage (top-level code, __VU==0) where modules load, and the VU stage (setup/default/teardown) where iterations execute. require() is bound only for the init context - the requireImpl guard in internal/js/bundle.go:456 checks it and throws when require is reached from VU-stage code. Module loading must happen once up front so every VU shares the same modules.","triggerScenarios":"Calling require('k6/http') (or any module) inside the exported default function, setup(), teardown(), handleSummary, or any helper they invoke; lazy/conditional require inside a function body.","commonSituations":"Refactors that move imports into functions 'for performance'; Node.js samples with lazy require() copied into iterations; attempting to load a different module per iteration or per VU.","solutions":["Move the require() call to the top level of the script (init stage)","Or switch to ESM: `import http from 'k6/http';` at the top of the file","For per-VU behavior, load the module once at init and branch on __VU inside the default function"],"exampleFix":"// before: require inside the default function\nexport default function () {\n  const http = require('k6/http');\n  http.get('https://k6.io');\n}\n\n// after: load in the init stage\nconst http = require('k6/http'); // or: import http from 'k6/http';\nexport default function () {\n  http.get('https://k6.io');\n}","handlingStrategy":"validation","validationCode":"# heuristic static check: require() on an indented line is inside a function (VU stage)\ngrep -nP '^[[:space:]]+.*\\brequire\\(' script.js && \\\n  { echo 'require() found outside top-level init code'; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all require() calls at the top of the file, column 0","Prefer ESM import statements - they are syntax-level and cannot be nested accidentally","During review, flag any require/open that moved into a function body"],"tags":["lifecycle","init-stage","commonjs","require","modules"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}