{"record":{"id":"856ed6c0d02e7bf2","repo":"grafana/k6","slug":"no-value-was-provided-for-metric-s-a-number-or","errorCode":null,"errorMessage":"no value was provided for metric '%s', a number or a boolean value is expected","messagePattern":"no value was provided for metric '(.+?)', a number or a boolean value is expected","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/js/modules/k6/metrics/metrics.go","lineNumber":97,"sourceCode":"\tif state == nil {\n\t\treturn false, ErrMetricsAddInInitContext\n\t}\n\n\t// return/throw exception if throw enabled, otherwise just log\n\traiseErr := func(err error) (bool, error) { //nolint:unparam // we want to just do `return raiseErr(...)`\n\t\tif state.Options.Throw.Bool {\n\t\t\treturn false, err\n\t\t}\n\t\tstate.Logger.Warn(err)\n\t\treturn false, nil\n\t}\n\traiseNan := func() (bool, error) {\n\t\treturn raiseErr(fmt.Errorf(\"'%s' is an invalid value for metric '%s', a number or a boolean value is expected\",\n\t\t\tlimitValue(v.String()), m.metric.Name))\n\t}\n\n\tif v == nil {\n\t\treturn raiseErr(fmt.Errorf(\"no value was provided for metric '%s', a number or a boolean value is expected\",\n\t\t\tm.metric.Name))\n\t}\n\tif sobek.IsNull(v) {\n\t\treturn raiseNan()\n\t}\n\n\tvfloat := v.ToFloat()\n\tif vfloat == 0 && v.ToBoolean() {\n\t\tvfloat = 1.0\n\t}\n\n\tif math.IsNaN(vfloat) {\n\t\treturn raiseNan()\n\t}\n\n\tctm := state.Tags.GetCurrentValues()\n\tif err := common.ApplyCustomUserTags(m.vu.Runtime(), &ctm, addTags); err != nil {\n\t\treturn false, fmt.Errorf(\"cannot add tags for the '%s' custom metric: %w\", m.metric.Name, err)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/metrics/metrics.go#L79-L115","documentation":"Produced by k6 custom metrics when .add() is called with no value argument at all. In Metric.add (internal/js/modules/k6/metrics/metrics.go:96-99) a nil sobek value (zero arguments) hits the v == nil branch. Like other metric value errors, it respects the throw option: with --throw it aborts the iteration with an exception; without it, it is logged as a warning and no sample is recorded.","triggerScenarios":"myCounter.add(); myTrend.add(undefined-as-missing-arg); calling add via apply with an empty array; a helper like track(name) that forwards ...args but receives none.","commonSituations":"Refactoring a helper from add(value, tags) to add(tags) and forgetting the value; optional chaining that drops the argument: myGauge.add(resp.json('value') ?? undefined) still counts as an argument, but a spread of an empty array does not; copy-paste boilerplate that never filled in the placeholder.","solutions":["Always pass an explicit first argument: counters commonly use 1 (myCounter.add(1, tags)), gauges/trends the measured value.","If the value is genuinely unavailable, skip the call instead of adding nothing.","Run with --throw during development so the warning becomes a stack-traced error pinpointing the call site."],"exampleFix":"// before\nfunction track(name, tags) { metrics[name].add(tags); }\ntrack('hits', { code: 200 }); // no value was provided\n\n// after\nfunction track(name, tags) { metrics[name].add(1, tags); }\ntrack('hits', { code: 200 });","handlingStrategy":"validation","validationCode":"function safeAdd(metric, value, tags) {\n  if (value === undefined) { metric.add(1, tags); return; } // counters default to 1\n  metric.add(value, tags);\n}","typeGuard":"const hasValue = (...args) => args.length > 0 && args[0] !== undefined;","tryCatchPattern":null,"preventionTips":["Make helper functions always pass an explicit value (1 for counters).","Use --throw in CI so a missing argument fails fast with a stack trace."],"tags":["metrics","validation","custom-metrics"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}