grafana/k6 · error

open() can't be used with files that weren't previously open

Error message

open() can't be used with files that weren't previously opened during initialization (__VU==0), path: %q

What it means

During init, k6 wraps the filesystem so only files actually opened at init are cached; in the VU stage open() is served from that cache (allowOnlyOpenedFiles / fsext.OnlyCachedEnabler in internal/js/initcontext.go). When a VU requests a path the cache has never seen, fsext returns ErrPathNeverRequestedBefore and readFile rewrites it into this error. The rule: every file must be opened unconditionally during initialization (__VU==0) so k6 can snapshot it for all VUs.

Source

Thrown at internal/js/initcontext.go:42

	filename = strings.TrimPrefix(filename, "file://")
	data, err := readFile(fs, fsext.Abs(basePWD.Path, filename))
	if err != nil {
		return nil, err
	}

	if len(args) > 0 && args[0] == "b" {
		ab := rt.NewArrayBuffer(data)
		return rt.ToValue(&ab), nil
	}
	return rt.ToValue(string(data)), nil
}

func readFile(fileSystem fsext.Fs, filename string) (data []byte, err error) {
	defer func() {
		if errors.Is(err, fsext.ErrPathNeverRequestedBefore) {
			// loading different files per VU is not supported, so all files should are going
			// to be used inside the scenario should be opened during the init step (without any conditions)
			err = fmt.Errorf(
				"open() can't be used with files that weren't previously opened during initialization (__VU==0), path: %q",
				filename,
			)
		}
	}()

	// Workaround for https://github.com/spf13/fsext/issues/201
	if isDir, err := fsext.IsDir(fileSystem, filename); err != nil {
		return nil, err
	} else if isDir {
		return nil, fmt.Errorf("open() can't be used with directories, path: %q", filename)
	}

	return fsext.ReadFile(fileSystem, filename)
}

// allowOnlyOpenedFiles enables seen only files
func allowOnlyOpenedFiles(fs fsext.Fs) {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Open every candidate file unconditionally at the top level during init - even files only some VUs use - and select among the loaded contents later
  2. For structured data, load and parse at init (SharedArray for large datasets) instead of calling open() in the VU
  3. If data is truly per-VU and huge, pre-generate one combined file or split the run into multiple scripts

Example fix

// before: per-VU path -> file never cached during init
export default function () {
  const data = JSON.parse(open(`./data/${__VU}.json`));
}

// after: open all files unconditionally at init, then pick per VU
import { SharedArray } from 'k6/data';
const shards = new SharedArray('shards', () => [
  JSON.parse(open('./data/1.json')),
  JSON.parse(open('./data/2.json')),
]);
export default function () {
  const data = shards[(__VU - 1) % shards.length];
}
Defensive patterns

Strategy: validation

Validate before calling

# heuristic: flag dynamic/interpolated paths inside open() - they cannot all be cached at init
grep -nP 'open\(\s*[`'"'"'].*\$\{|open\(.*\+' script.js && \
  echo 'warning: dynamic open() path - open every file unconditionally during init instead'

Prevention

When it happens

Trigger: Opening a per-VU path such as open(`data_${__VU}.json`) inside the default function; opening file A during init only under a condition (if (__ENV.MODE) open('a.csv')) so a different path is requested later; calling open() in the VU stage on a path never touched at init.

Common situations: Sharding test data per VU; environment-dependent fixtures; code that opens a fallback file only on some branches; loading different files per iteration.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/1d8d928ddb73426e. Report an issue: GitHub.