grafana/k6 · error

error while parsing use directives constraint %q for %q in %

Error message

error while parsing use directives constraint %q for %q in %q: %w

What it means

Produced while processing `use k6 ...` version directives found in the script and its imported files (the launcher parses lines like `use k6 >= v0.50` or `use k6 with k6/x/example v0.3.0`). After cutting off the dependency name, any remaining text is fed to semver.NewConstraint, and text that is not a valid semver constraint range produces this error, which includes the bad constraint, the dependency, and the file where the directive was found.

Source

Thrown at internal/cmd/launcher.go:406

	for _, directive := range directives {
		// normalize spaces
		directive = strings.ReplaceAll(directive, "  ", " ")
		if !strings.HasPrefix(directive, "use k6") {
			continue
		}
		directive = strings.TrimSpace(strings.TrimPrefix(directive, "use k6"))
		dep := "k6"
		constraint := directive
		if strings.HasPrefix(directive, "with k6/x/") {
			directive = strings.TrimSpace(strings.TrimPrefix(directive, "with "))
			dep, constraint, _ = strings.Cut(directive, " ")
		}
		var con *semver.Constraints
		var err error
		if len(constraint) > 0 {
			con, err = semver.NewConstraint(constraint)
			if err != nil {
				return fmt.Errorf("error while parsing use directives constraint %q for %q in %q: %w", constraint, dep, name, err)
			}
		}

		err = deps.update(dep, con)
		if err != nil {
			return fmt.Errorf("error while parsing use directives in %q: %w", name, err)
		}
	}

	return nil
}

func findDirectives(text []byte) []string {
	// parse #! at beginning of file
	if bytes.HasPrefix(text, []byte("#!")) {
		_, text, _ = bytes.Cut(text, []byte("\n"))
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Read the error: it quotes the exact bad constraint, the dependency, and the file — open that file's directive line
  2. Rewrite the constraint as a valid semver range: `use k6 >= v0.50.0`, `use k6 v0.50.0`, or `use k6 with k6/x/sql 0.x`
  3. Avoid bare words like latest/next — pin an explicit version or range
  4. Re-run; if multiple directives exist, fix them one at a time (each parse failure reports its file)

Example fix

// before (script.js)
use k6 latest
export default function () {}
// error: error while parsing use directives constraint "latest" for "k6" in "script.js"

// after
use k6 >= v0.56.0
export default function () {}
Defensive patterns

Strategy: validation

Validate before calling

# Lint all use-directives against semver range syntax before running
node -e '
const {validRange} = require("semver");
const fs = require("fs");
for (const f of process.argv.slice(1)) {
  const m = fs.readFileSync(f, "utf8").match(/^use\s+k6.*$/gm) || [];
  for (const line of m) {
    const c = line.replace(/^use\s+k6(\s+with)?/, "").trim().split(/\s+/).pop();
    if (c && !validRange(c)) { console.error(`bad constraint ${c} in ${f}`); process.exitCode = 1; }
  }
}' main.js lib/*.js

Type guard

function isValidK6UseConstraint(c) {
  // cheap check: comparator(optional) + dotted version, e.g. ">=v0.56.0", "0.x", "v1.2.3"
  return /^(>=|<=|>|<|=|~|\^)?\s*v?\d+(\.\d+|\.x)+(\s+-\s+(>=|<=|>|<|=|~|\^)?\s*v?\d+(\.\d+|\.x)+)?$/.test(c.trim());
}

Prevention

When it happens

Trigger: A directive such as `use k6 v50` (missing minor/patch), `use k6 => latest`, `use k6 with k6/x/foo == 1` (incomplete comparator), or stray text after `use k6` like `use k6 and above`; also copy-pasting npm-style selectors (e.g. `^`, `~` are fine but `latest`, `next`, or bare `>` with no version are not).

Common situations: Teams migrating from npm-style version pinning habits; LLM/snippet-sourced scripts with plausible-but-invalid directives; typos like `>=v0.5.0 ` with invisible trailing characters; multiple scripts where one import's header directive is malformed.

Related errors


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