grafana/k6 · error
the "open" function is only available in the init stage (i.e
Error message
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
What it means
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.
Source
Thrown at internal/js/bundle.go:478
func (b *Bundle) setInitGlobals(rt *sobek.Runtime, vu *moduleVUImpl, modSys *modules.ModuleSystem) {
mustSet := func(k string, v any) {
if err := rt.Set(k, v); err != nil {
panic(fmt.Errorf("failed to set '%s' global object: %w", k, err))
}
}
impl := requireImpl{
inInitContext: func() bool { return vu.state == nil },
modSys: modSys,
}
mustSet("require", impl.require)
mustSet("open", func(filename string, args ...string) (sobek.Value, error) {
// TODO fix in stack traces
if vu.state != nil {
return nil, fmt.Errorf(cantBeUsedOutsideInitContextMsg, "open")
}
if filename == "" {
return nil, errors.New("open() can't be used with an empty filename")
}
// This uses the pwd from the requireImpl
pwd, err := modSys.CurrentlyRequiredModule()
if err != nil {
return nil, err
}
if !strings.HasPrefix(filename, "file://") && !filepath.IsAbs(filename) {
otherPath, shouldWarn := modSys.ShouldWarnOnParentDirNotMatchingCurrentModuleParentDir(vu, pwd)
logger := b.preInitState.Logger
if shouldWarn {
logger.Warningf("open() was used and is currently relative to '%s', but in the future "+
"it will be aligned with how `require` and imports work and will be relative to '%s'. This means "+
"that in the future open will open relative path relative to the module/file it is written in. "+
"You can future proof this by using `import.meta.resolve()` to get relative paths to the file it "+View on GitHub (pinned to 93accf6570)
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
Example fix
// before: open() inside the default function
export default function () {
const data = JSON.parse(open('./users.json'));
}
// after: read at init, share via SharedArray
import { SharedArray } from 'k6/data';
const users = new SharedArray('users', () => JSON.parse(open('./users.json')).users);
export default function () {
const user = users[__ITER % users.length];
} Defensive patterns
Strategy: validation
Validate before calling
# heuristic static check: open() on an indented line runs in the VU stage
grep -nP '^[[:space:]]+.*\bopen\(' script.js && \
{ echo 'open() found outside top-level init code'; exit 1; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- open() can't be used with files that weren't previously open
- the "require" function is only available in the init stage (
- open() can't be used with directories, path: %q
- exported 'setup' must be a function
- exported 'teardown' must be a function
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/7fa6690109cdd473.
Report an issue: GitHub.