grafana/k6 · warning
'%s' is an invalid value for metric '%s', a number or a bool
Error message
'%s' is an invalid value for metric '%s', a number or a boolean value is expected
What it means
Produced by k6 custom metrics (Counter/Gauge/Trend/Rate .add()) when the value argument cannot be interpreted as a number. In Metric.add (internal/js/modules/k6/metrics/metrics.go:91-111) this fires for sobek null values and for values whose ToFloat() is NaN (e.g. non-numeric strings, NaN, undefined coaxed to string). Behavior depends on the throw option: with --throw (or options.throw=true) it raises as an exception; otherwise it is only logged as a warning and the sample is DROPPED (add returns false).
Source
Thrown at internal/js/modules/k6/metrics/metrics.go:92
}, string(omitMsg))
}
func (m Metric) add(v sobek.Value, addTags sobek.Value) (bool, error) {
state := m.vu.State()
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()View on GitHub (pinned to 93accf6570)
Solutions
- If the message appears as a warning: run once with --throw to turn it into a failing exception with a stack trace pointing at the exact add() call.
- Sanitize before adding: Number.isFinite(Number(v)) ? v : 0 (or skip the sample).
- Coerce stringly-typed fields explicitly: myTrend.add(Number(resp.json('price'))).
- Guard optional fields: if (value !== null && value !== undefined) myGauge.add(value).
Example fix
// before const latency = parseFloat(resp.headers['X-Latency']); // NaN when header missing myTrend.add(latency); // after const latency = parseFloat(resp.headers['X-Latency']); if (Number.isFinite(latency)) myTrend.add(latency);
Defensive patterns
Strategy: validation
Validate before calling
function safeAdd(metric, value, tags) {
if (value === null || value === undefined) return false;
if (typeof value === 'number' && !Number.isFinite(value)) return false;
if (typeof value !== 'number' && typeof value !== 'boolean') {
const n = Number(value);
if (!Number.isFinite(n)) return false;
}
metric.add(value, tags);
return true;
} Type guard
const isMetricValue = (v) => typeof v === 'boolean' || (typeof v === 'number' && Number.isFinite(v));
Try / catch
try { metric.add(value); } catch (e) { if (/is an invalid value for metric/.test(e.message)) { /* coerce or skip, log once */ } else throw e; } Prevention
- Run scripts with --throw during development to surface dropped samples as errors.
- Number.isFinite(Number(x)) guard before adding parsed/untyped values.
- Log a single diagnostic when a sample is skipped so silent data loss is visible in results.
When it happens
Trigger: myCounter.add('abc'); myTrend.add(NaN); myRate.add(null); myGauge.add({v: 1}) (object coerced to NaN string); myTrend.add('12px') — strings that are not pure numeric literals fail v.ToFloat(). Booleans are fine (true becomes 1.0, false 0 via the ToBoolean branch).
Common situations: Feeding parseFloat results without checking NaN (e.g. parsing a response header that is sometimes missing); passing JSON fields that are strings in one response and numbers in another; null from optional fields; the silent warning variant hides the problem until results show missing samples.
Related errors
- no value was provided for metric '%s', a number or a boolean
- cannot add tags for the '%s' custom metric: %w
- invalid metric type
- invalid threshold
- invalid value type
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/eaedacdb01251f60.
Report an issue: GitHub.