{"record":{"id":"079b3aebc6fe5154","repo":"grafana/k6","slug":"group-does-not-support-async-functions-as-arguments-unless","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/k6.go","lineNumber":117,"sourceCode":"// Group executes a callback under the provided group name.\n//\n// With the async-metric-context feature enabled, async callbacks retain their metric\n// context through promise reactions and group_duration covers their lifetime.\nfunc (mi *K6) Group(name string, val sobek.Value) (sobek.Value, error) {\n\tstate := mi.vu.State()\n\tif state == nil {\n\t\treturn nil, ErrGroupInInitContext\n\t}\n\n\tif common.IsNullish(val) {\n\t\treturn nil, errors.New(\"group() requires a callback as a second argument\")\n\t}\n\tfn, ok := sobek.AssertFunction(val)\n\tif !ok {\n\t\treturn nil, errors.New(\"group() requires a callback as a second argument\")\n\t}\n\tif !mi.asyncGroups && common.IsAsyncFunction(mi.vu.Runtime(), val) {\n\t\treturn sobek.Undefined(), errors.New(\"group() does not support async functions as arguments \" +\n\t\t\t\"unless the async-metric-context experimental feature is enabled \" +\n\t\t\t\"(pass --features async-metric-context or set K6_FEATURES=async-metric-context), \" +\n\t\t\t\"please see https://grafana.com/docs/k6/latest/javascript-api/k6/group/ for more info\")\n\t}\n\n\tparentTagsAndMeta := state.Tags.GetCurrentValues()\n\toldGroupName, _ := parentTagsAndMeta.Tags.Get(metrics.TagGroup.String())\n\tnewGroupName, err := lib.NewGroupPath(oldGroupName, name)\n\tif err != nil {\n\t\treturn sobek.Undefined(), err\n\t}\n\n\tshouldUpdateTag := state.Options.SystemTags.Has(metrics.TagGroup)\n\tif shouldUpdateTag {\n\t\tsetGroupTag(state, newGroupName)\n\t}\n\tvar groupTagsAndMeta metrics.TagsAndMeta\n\tif mi.asyncGroups {","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/grafana/k6/blob/3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee/internal/js/modules/k6/k6.go#L99-L135","documentation":"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.","triggerScenarios":"Calling group('name', async () => {...}) in a test script while the async-metric-context experimental feature is disabled (default).","commonSituations":"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.","solutions":["Remove async from the group callback and keep it synchronous (use http.* synchronous APIs).","Enable the experimental feature: run k6 with --features async-metric-context or set K6_FEATURES=async-metric-context.","Move the async work (e.g. promises, setTimeout-based waits) outside the group() call."],"exampleFix":"// before\ngroup('login', async () => {\n  await doLogin();\n});\n// after\ngroup('login', () => {\n  doLogin(); // synchronous k6 APIs\n});\n// or run: k6 --features async-metric-context run script.js","handlingStrategy":"validation","validationCode":"// In script, before grouping:\nif (cb.constructor && cb.constructor.name === 'AsyncFunction') {\n  throw new Error('group() callback must be synchronous');\n}","typeGuard":"function isSyncFunction(fn) {\n  return typeof fn === 'function' &&\n    Object.prototype.toString.call(fn) !== '[object AsyncFunction]';\n}","tryCatchPattern":"try {\n  group('name', cb);\n} catch (e) {\n  if (String(e).includes('async-metric-context')) {\n    group('name', () => { /* sync version */ });\n  } else { throw e; }\n}","preventionTips":["Keep group() callbacks synchronous; do async work outside the group.","If async grouping is required, enable --features async-metric-context in the run command and CI pipeline.","Lint test scripts for 'group(' followed by 'async'."],"tags":["k6","async","javascript","experimental-feature","groups"],"backgroundTag":"feature-not-enabled","analyzedSha":"3fcf5388d78cb382f0c0d42ec556a06bfd1b8dee","analyzedAt":"2026-09-20T22:01:45.163Z","contentChangedAt":"2026-09-20T22:01:45.163Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}