grafana/k6 · error · ErrInvalidValueType

invalid value type

Error message

invalid value type

What it means

ErrInvalidValueType (metrics/value_type.go:13) is returned by ValueType.UnmarshalText (line 51) when the input string is not 'default', 'time', or 'data', and by MarshalText (line 37) for an out-of-range ValueType integer. ValueType declares how metric values are rendered (as-is, milliseconds, bytes); it round-trips through JSON in metric definitions inside archives, the registry, and output payloads.

Source

Thrown at metrics/value_type.go:13

package metrics

import "errors"

// Possible values for ValueType.
const (
	Default = ValueType(iota) // Values are presented as-is
	Time                      // Values are time durations (milliseconds)
	Data                      // Values are data amounts (bytes)
)

// ErrInvalidValueType indicates the serialized value type is invalid.
var ErrInvalidValueType = errors.New("invalid value type")

// ValueType holds the type of values a metric contains.
type ValueType int

// MarshalJSON serializes a ValueType to a JSON string.
func (t ValueType) MarshalJSON() ([]byte, error) {
	txt, err := t.MarshalText()
	if err != nil {
		return nil, err
	}
	return []byte(`"` + string(txt) + `"`), nil
}

// MarshalText serializes a ValueType as a human readable string.
func (t ValueType) MarshalText() ([]byte, error) {
	switch t {
	case Default:
		return []byte(defaultString), nil

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use exactly one of: default, time, data (lowercase)
  2. Translate domain units to k6's names before deserializing (bytes -> data, ms -> time)
  3. Validate external strings against the accepted set before unmarshaling

Example fix

// before
var vt metrics.ValueType
err := json.Unmarshal([]byte(`"bytes"`), &vt) // ErrInvalidValueType

// after
var vt metrics.ValueType
err := json.Unmarshal([]byte(`"data"`), &vt)
Defensive patterns

Strategy: type-guard

Validate before calling

// Go: whitelist check before unmarshaling
var validValueTypes = map[string]bool{"default": true, "time": true, "data": true}
if !validValueTypes[input] {
    return fmt.Errorf("unsupported value type %q; want default|time|data", input)
}

Type guard

// Go
func isValidValueType(s string) bool {
    switch s {
    case "default", "time", "data":
        return true
    }
    return false
}

Try / catch

// Go
if err := json.Unmarshal(data, &vt); err != nil {
    if errors.Is(err, metrics.ErrInvalidValueType) {
        // map unit names (bytes->data, ms->time) and retry, or reject the payload
    }
}

Prevention

When it happens

Trigger: json.Unmarshal of '"duration"', '"ms"', '"bytes"', or '"DATA"' (case-sensitive) into a metrics.ValueType field; marshaling ValueType(9). The only accepted strings are default, time, data.

Common situations: Exchanging metric metadata with tools that use different unit names ('bytes' vs 'data', 'ms' vs 'time'); hand-written JSON archives; case mismatches from template engines.

Related errors


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