grafana/k6 · warning

no value was provided for metric '%s', a number or a boolean

Error message

no value was provided for metric '%s', a number or a boolean value is expected

What it means

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.

Source

Thrown at internal/js/modules/k6/metrics/metrics.go:97

	if state == nil {
		return false, ErrMetricsAddInInitContext
	}

	// return/throw exception if throw enabled, otherwise just log
	raiseErr := func(err error) (bool, error) { //nolint:unparam // we want to just do `return raiseErr(...)`
		if state.Options.Throw.Bool {
			return false, err
		}
		state.Logger.Warn(err)
		return false, nil
	}
	raiseNan := func() (bool, error) {
		return raiseErr(fmt.Errorf("'%s' is an invalid value for metric '%s', a number or a boolean value is expected",
			limitValue(v.String()), m.metric.Name))
	}

	if v == nil {
		return raiseErr(fmt.Errorf("no value was provided for metric '%s', a number or a boolean value is expected",
			m.metric.Name))
	}
	if sobek.IsNull(v) {
		return raiseNan()
	}

	vfloat := v.ToFloat()
	if vfloat == 0 && v.ToBoolean() {
		vfloat = 1.0
	}

	if math.IsNaN(vfloat) {
		return raiseNan()
	}

	ctm := state.Tags.GetCurrentValues()
	if err := common.ApplyCustomUserTags(m.vu.Runtime(), &ctm, addTags); err != nil {
		return false, fmt.Errorf("cannot add tags for the '%s' custom metric: %w", m.metric.Name, err)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Always pass an explicit first argument: counters commonly use 1 (myCounter.add(1, tags)), gauges/trends the measured value.
  2. If the value is genuinely unavailable, skip the call instead of adding nothing.
  3. Run with --throw during development so the warning becomes a stack-traced error pinpointing the call site.

Example fix

// before
function track(name, tags) { metrics[name].add(tags); }
track('hits', { code: 200 }); // no value was provided

// after
function track(name, tags) { metrics[name].add(1, tags); }
track('hits', { code: 200 });
Defensive patterns

Strategy: validation

Validate before calling

function safeAdd(metric, value, tags) {
  if (value === undefined) { metric.add(1, tags); return; } // counters default to 1
  metric.add(value, tags);
}

Type guard

const hasValue = (...args) => args.length > 0 && args[0] !== undefined;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/856ed6c0d02e7bf2. Report an issue: GitHub.