{"record":{"id":"67e02b4307574f3f","repo":"grafana/k6","slug":"no-checks-provided-to-check","errorCode":null,"errorMessage":"no checks provided to `check`","messagePattern":"no checks provided to `check`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/k6.go","lineNumber":153,"sourceCode":"\t\t\tMetric: state.BuiltinMetrics.GroupDuration,\n\t\t\tTags:   ctm.Tags,\n\t\t},\n\t\tTime:     t,\n\t\tValue:    metrics.D(t.Sub(startTime)),\n\t\tMetadata: ctm.Metadata,\n\t})\n\n\treturn ret, err\n}\n\n// Check will emit check metrics for the provided checks.\nfunc (mi *K6) Check(arg0, checks sobek.Value, extras ...sobek.Value) (bool, error) {\n\tstate := mi.vu.State()\n\tif state == nil {\n\t\treturn false, ErrCheckInInitContext\n\t}\n\tif checks == nil {\n\t\treturn false, errors.New(\"no checks provided to `check`\")\n\t}\n\tctx := mi.vu.Context()\n\trt := mi.vu.Runtime()\n\tt := time.Now()\n\n\t// Prepare the metric tags\n\tcommonTagsAndMeta := state.Tags.GetCurrentValues()\n\tif len(extras) > 0 {\n\t\tif err := common.ApplyCustomUserTags(rt, &commonTagsAndMeta, extras[0]); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t}\n\n\tsucc := true\n\tvar exc error\n\tobj := checks.ToObject(rt)\n\tfor _, name := range obj.Keys() {\n\t\tif strings.Contains(name, lib.GroupSeparator) {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/k6.go#L135-L171","documentation":"`k6.check(value, checks)` emits one check metric per entry of the checks object. At internal/js/modules/k6/k6.go:148 the checks argument is tested for nil — when the argument is omitted entirely, sobek passes a nil Value and k6 throws \"no checks provided to `check`\". A check call with no assertions has nothing to record, so k6 rejects it rather than silently passing.","triggerScenarios":"`k6.check(res)` with the second argument missing entirely (note: this nil check only fires for an absent argument; passing undefined explicitly gets past it and iterates zero keys).","commonSituations":"Building checks dynamically and passing an accidentally undefined variable; refactors that drop the object; tutorials where the second argument is on a lost line.","solutions":["Supply the checks object: `k6.check(res, { 'status is 200': (r) => r.status === 200 })`","When checks are dynamic, default to an empty object and populate it: `k6.check(res, checks || {})` — or skip the call if empty","Verify the variable holding the checks object is defined"],"exampleFix":"// before\nconst checks = buildChecks(res); // returns undefined\nk6.check(res, checks);\n\n// after\nconst checks = buildChecks(res) || {};\nk6.check(res, checks);","handlingStrategy":"validation","validationCode":"const hasChecks = checks !== undefined;\nif (!hasChecks) { /* skip or supply fallback */ }\nif (hasChecks) k6.check(res, checks);","typeGuard":null,"tryCatchPattern":"try {\n  k6.check(res, checks);\n} catch (e) {\n  if (String(e.message).includes('no checks provided')) throw new Error('checks object was not passed to k6.check');\n  throw e;\n}","preventionTips":["Always pass the checks object literal as the second argument","Default dynamic checks: k6.check(res, checks || {}) or skip the call when empty","Build checks objects in one place and assert they are non-empty before use"],"tags":["k6-api","javascript","validation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}