grafana/k6 · error

unmarshaling %q to ColorScheme: %w

Error message

unmarshaling %q to ColorScheme: %w

What it means

ColorScheme.UnmarshalJSON tried to json.Unmarshal the raw bytes into a Go string and failed — the value for the colorScheme option is not a JSON string. As with ReducedMotion, an unknown string quietly becomes the zero value ('no-preference'); the error only fires for non-string JSON (numbers, booleans, objects, malformed input).

Source

Thrown at internal/js/modules/k6/browser/common/page.go:169

	"light":         ColorSchemeLight,
	"dark":          ColorSchemeDark,
	"no-preference": ColorSchemeNoPreference,
}

// MarshalJSON marshals the enum as a quoted JSON string.
func (c ColorScheme) MarshalJSON() ([]byte, error) {
	buffer := bytes.NewBufferString(`"`)
	buffer.WriteString(colorSchemeToString[c])
	buffer.WriteString(`"`)
	return buffer.Bytes(), nil
}

// UnmarshalJSON unmarshals a quoted JSON string to the enum value.
func (c *ColorScheme) UnmarshalJSON(b []byte) error {
	var j string
	err := json.Unmarshal(b, &j)
	if err != nil {
		return fmt.Errorf("unmarshaling %q to ColorScheme: %w", b, err)
	}
	// Note that if the string cannot be found then it will be set to the zero value.
	*c = colorSchemeToID[j]
	return nil
}

// EmulatedSize represents the emulated viewport and screen sizes.
type EmulatedSize struct {
	Viewport Viewport
	Screen   Screen
}

// NewEmulatedSize creates and returns a new EmulatedSize.
func NewEmulatedSize(viewport Viewport, screen Screen) *EmulatedSize {
	return &EmulatedSize{
		Viewport: viewport,
		Screen:   screen,
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use the string values 'light', 'dark', or 'no-preference' for colorScheme
  2. Check the serialized form (k6 inspect) if options flow in from --config or env
  3. Add a small assert in the script that typeof options-browser colorScheme is 'string' before creating the context

Example fix

// before
const ctx = browser.newContext({ colorScheme: 2 }); // not a string

// after
const ctx = browser.newContext({ colorScheme: 'dark' });
Defensive patterns

Strategy: type-guard

Validate before calling

const cs = opts.colorScheme;
if (cs !== undefined && typeof cs !== 'string') { throw new TypeError('colorScheme must be a string: "light" | "dark" | "no-preference"'); }

Type guard

function isValidColorScheme(v) {
  return v === undefined || v === 'light' || v === 'dark' || v === 'no-preference';
}

Prevention

When it happens

Trigger: Passing colorScheme as a non-string to browser.newContext/newPage, e.g. colorScheme: 0, colorScheme: ['dark'], or an object; or supplying the option through serialized JSON config where it lost its string type.

Common situations: Dynamic option generation that inserts constants/numbers; config files where quotes were stripped; ported Playwright scripts using different enum representations.

Related errors


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