grafana/k6 · error

group() does not support async functions as arguments…

Error message

group() does not support async functions as arguments unless the async-metric-context experimental feature is enabled (pass --features async-metric-context or set K6_FEATURES=async-metric-context), please see https://grafana.com/docs/k6/latest/javascript-api/k6/group/ for more info

What it means

k6's group() runs its callback inside a metrics-tagging context synchronously. Async callbacks would lose/interleave that context, so k6 rejects them unless the async-metric-context experimental feature is enabled.

Solutions

  1. Remove async from the group callback and keep it synchronous (use http.* synchronous APIs).
  2. Enable the experimental feature: run k6 with --features async-metric-context or set K6_FEATURES=async-metric-context.
  3. Move the async work (e.g. promises, setTimeout-based waits) outside the group() call.

Example fix

// before
group('login', async () => {
  await doLogin();
});
// after
group('login', () => {
  doLogin(); // synchronous k6 APIs
});
// or run: k6 --features async-metric-context run script.js
Defensive patterns

Strategy: validation

Validate before calling

// In script, before grouping:
if (cb.constructor && cb.constructor.name === 'AsyncFunction') {
  throw new Error('group() callback must be synchronous');
}

Type guard

function isSyncFunction(fn) {
  return typeof fn === 'function' &&
    Object.prototype.toString.call(fn) !== '[object AsyncFunction]';
}

Try / catch

try {
  group('name', cb);
} catch (e) {
  if (String(e).includes('async-metric-context')) {
    group('name', () => { /* sync version */ });
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling group('name', async () => {...}) in a test script while the async-metric-context experimental feature is disabled (default).

Common situations: Refactoring a normal group callback to async/await to use await inside checks or requests; copying examples using async arrow functions into group(); k6 version upgrades where scripts started using async callbacks.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-09-20). Data as JSON: /api/errors/079b3aebc6fe5154. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/k6.go:117

// Group executes a callback under the provided group name.
//
// With the async-metric-context feature enabled, async callbacks retain their metric
// context through promise reactions and group_duration covers their lifetime.
func (mi *K6) Group(name string, val sobek.Value) (sobek.Value, error) {
	state := mi.vu.State()
	if state == nil {
		return nil, ErrGroupInInitContext
	}

	if common.IsNullish(val) {
		return nil, errors.New("group() requires a callback as a second argument")
	}
	fn, ok := sobek.AssertFunction(val)
	if !ok {
		return nil, errors.New("group() requires a callback as a second argument")
	}
	if !mi.asyncGroups && common.IsAsyncFunction(mi.vu.Runtime(), val) {
		return sobek.Undefined(), errors.New("group() does not support async functions as arguments " +
			"unless the async-metric-context experimental feature is enabled " +
			"(pass --features async-metric-context or set K6_FEATURES=async-metric-context), " +
			"please see https://grafana.com/docs/k6/latest/javascript-api/k6/group/ for more info")
	}

	parentTagsAndMeta := state.Tags.GetCurrentValues()
	oldGroupName, _ := parentTagsAndMeta.Tags.Get(metrics.TagGroup.String())
	newGroupName, err := lib.NewGroupPath(oldGroupName, name)
	if err != nil {
		return sobek.Undefined(), err
	}

	shouldUpdateTag := state.Options.SystemTags.Has(metrics.TagGroup)
	if shouldUpdateTag {
		setGroupTag(state, newGroupName)
	}
	var groupTagsAndMeta metrics.TagsAndMeta
	if mi.asyncGroups {

View on GitHub (pinned to 3fcf5388d7)