grafana/k6 · error

error while parsing use directives in %q: %w

Error message

error while parsing use directives in %q: %w

What it means

Emitted right after constraint parsing while processing `use` directives: the parsed dependency/constraint pair is merged into the dependency set with deps.update, which errors with 'already have constraint for %q, when parsing %q' when a second, different constraint arrives for a dependency that already has a non-star constraint. Only the first meaningful constraint for a dependency is kept; a conflicting second one is rejected.

Source

Thrown at internal/cmd/launcher.go:412

		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"))
	}

	var result []string

	for i := 0; i < len(text); {
		r, width := utf8.DecodeRune(text[i:])
		switch {
		case unicode.IsSpace(r) || r == rune(';'): // skip all spaces and ;

View on GitHub (pinned to 93accf6570)

Solutions

  1. Locate every `use` directive across the entry script and all local imports: `grep -rn "^use " .`
  2. Make the constraints identical for the conflicting dependency, or remove the duplicate from the less authoritative file
  3. If files legitimately need different versions, align them to one range (e.g. both `>= v0.56.0`)
  4. Re-run k6; only the first conflict is reported at a time, so repeat until clean

Example fix

// before
// main.js: use k6 >= v0.56.0
// lib/helpers.js: use k6 v0.55.0
// error: error while parsing use directives in "lib/helpers.js": already have constraint for "k6", ...

// after
// lib/helpers.js: use k6 >= v0.56.0
Defensive patterns

Strategy: validation

Validate before calling

# Detect duplicate/conflicting use directives across entry + local imports before running
grep -rhoE '^use k6( with [^ ]+)? .*' --include='*.js' . | sort | uniq -d
# any output means the same dependency is constrained more than once — align them

Type guard

function conflictingDeps(directivesPerFile) {
  const seen = new Map();
  for (const [file, lines] of Object.entries(directivesPerFile)) {
    for (const l of lines) {
      const m = l.match(/^use\s+k6\s+(.*)$/); if (!m) continue;
      if (seen.has(m[1]) && seen.get(m[1]).file !== file) return { conflict: m[1], files: [seen.get(m[1]).file, file] };
      seen.set(m[1], { file });
    }
  }
  return null;
}

Prevention

When it happens

Trigger: Two `use k6` directives with different constraints in one file (`use k6 >= v0.50` then `use k6 < v0.50`), or constraints spread across files: the main script pins `use k6 v0.56.0` while an imported helper's header says `use k6 v0.55.0`; the same applies to extensions like k6/x/foo constrained differently in two places. Repeating the identical constraint, or going from an unconstrained/star constraint to a specific one, is allowed.

Common situations: Shared helper modules copied between projects that carry their own `use` headers; bumping the version in the entry script but not in imported local files; a dependency manifest (K6_DEPENDENCIES) interacting with directives — the manifest fills only unconstrained entries, then a conflicting directive arrives.

Related errors


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