{"record":{"id":"25503c8f01806929","repo":"grafana/k6","slug":"group-and-check-names-may-not-contain","errorCode":null,"errorMessage":"group and check names may not contain '::'","messagePattern":"group and check names may not contain '::'","errorType":"validation","errorClass":"ErrNameContainsGroupSeparator","httpStatus":null,"severity":"error","filePath":"lib/models.go","lineNumber":29,"sourceCode":"\t\"time\"\n\n\t\"gopkg.in/guregu/null.v3\"\n\n\t\"go.k6.io/k6/v2/lib/types\"\n)\n\n// GroupSeparator for group IDs.\nconst GroupSeparator = \"::\"\n\n// RootGroupPath is the id of the root group\n//\n// Note(@mstoykov): the constant shouldn't be used in all tests in order to not couple the tests too much with it.\n// Changing this will be a breaking change and in this way it will be more obvious.\nconst RootGroupPath = \"\"\n\nvar (\n\t// ErrNameContainsGroupSeparator is emitted if you attempt to instantiate a Group or Check that contains the separator.\n\tErrNameContainsGroupSeparator = errors.New(\"group and check names may not contain '\" + GroupSeparator + \"'\")\n\n\t// ErrCheckGroupIsNil is emitted if you attempt to instantiate a Check (see NewCheck) with a nil Group.\n\tErrCheckGroupIsNil = errors.New(\"check's group must not be nil\")\n)\n\n// StageFields defines the fields used for a Stage; this is a dumb hack to make the JSON code\n// cleaner. pls fix.\ntype StageFields struct {\n\t// Duration of the stage.\n\tDuration types.NullDuration `json:\"duration\"`\n\n\t// If Valid, the VU count will be linearly interpolated towards this value.\n\tTarget null.Int `json:\"target\"`\n}\n\n// A Stage defines a step in a test's timeline.\ntype Stage StageFields\n","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/lib/models.go#L11-L47","documentation":"ErrNameContainsGroupSeparator (lib/models.go:29) is returned by lib.NewGroup and lib.NewCheck when the requested name contains '::'. '::' (GroupSeparator, line 22) is reserved: group IDs are built by joining the group hierarchy path with '::' (e.g. group('a') then group('b') inside it yields id 'a::b'), so allowing it inside a name would corrupt path semantics for Group.FindByPath and metric tagging.","triggerScenarios":"Calling group('login::slow') or check(res, { 'a::b': r => r.ok }) in a k6 script; NewGroup/NewCheck parse the name and return this sentinel error before creating the object.","commonSituations":"Teams using '::' as a visual namespace separator in names ('api::v2::users'), or porting naming conventions from other tools (RSpec/Rust style) where '::' is idiomatic.","solutions":["Remove '::' from the group/check name; use a single '-' or '_' separator instead","If hierarchy is the goal, nest group() calls — the path is joined with '::' automatically: group('api', () => { group('v2', ...) }) yields 'api::v2'"],"exampleFix":"// before\ngroup('api::users', () => { http.get('https://test.k6.io/users'); });\n\n// after\ngroup('api', () => {\n  group('users', () => { http.get('https://test.k6.io/users'); });\n});","handlingStrategy":"validation","validationCode":"// Guard names before calling group()/check()\nconst safeName = (n) => {\n  if (n.includes('::')) throw new Error(`name must not contain '::': ${n}`);\n  return n;\n};\ngroup(safeName(userDefined), () => { /* ... */ });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use '-' in group/check names; reserve '::' for k6's internal path joining","Build hierarchy with nested group() calls instead of encoding paths in names"],"tags":["scripting","groups","checks","validation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}