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
- Use the string values 'light', 'dark', or 'no-preference' for colorScheme
- Check the serialized form (k6 inspect) if options flow in from --config or env
- 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
- Pass colorScheme as a string literal: 'light', 'dark', or 'no-preference'
- Validate serialized option sources (config files, env vars) for type, not just presence
- Unknown strings silently fall back to 'no-preference' — assert the exact value you intend
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
- unmarshaling %q to ReducedMotion: %w
- unmarshalling options for SDK: %w
- unmarshaling polling type: %w
- parsing goto options: %w
- parsing setContent options: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/9c61bd1efd17f092.
Report an issue: GitHub.