grafana/k6 · warning
unmarshaling hosts option
Error message
unmarshaling hosts option: %w
What it means
After marshaling the k6 hosts option to JSON, the browser module unmarshals it into map[string]string to build Chromium's --host-resolver-rules. This error means the unmarshal step produced something that is not a string-to-string map. With the current types.NullHosts representation this is a defensive, near-unreachable path; it would only fire if the JSON shape of the hosts option ever stops being a flat string map.
Solutions
- Check the hosts option for non-string values (numbers, objects) and make every value a plain string
- Remove the hosts option and re-run to isolate the trigger
- Align k6 and the browser module on one version (upgrade)
- Report upstream with the exact hosts value if it reproduces on stock k6
Example fix
// before
export const options = { hosts: { 'test.k6.io': 12345 } };
// after
export const options = { hosts: { 'test.k6.io': '1.2.3.4:80' } }; Defensive patterns
Strategy: validation
Validate before calling
// Validate that every hosts value is a string before launching
const hosts = (options.hosts ||= {});
for (const [k, v] of Object.entries(hosts)) {
if (typeof v !== 'string') throw new Error(`hosts['${k}'] must be a string, got ${typeof v}`);
} Prevention
- Never put numbers or objects into the hosts option
- Re-verify hosts config after k6 upgrades
- Report reproduction cases on stock k6 upstream
When it happens
Trigger: Same launch path as [600]: browser start with the `hosts` option set, and the marshaled JSON of NullHosts not decoding into map[string]string. Realistic only across k6 versions whose hosts option JSON representation changed, or with values that are not strings.
Common situations: Version-skewed k6 installs; custom builds; effectively never on released k6 because NullHosts always encodes as {"host":"ip"}.
Related errors
- marshaling hosts option
- unmarshalling options for SDK
- missing presigned url in response body
- parse isChecked options of selector
- parse isDisabled options of selector
AI-assisted analysis of grafana/k6@8d06114777 (2026-08-18).
Data as JSON: /api/errors/69d92a095242b470.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/chromium/browser_type.go:537
// Add the host resolver rules.
//
// This is done by marshaling the k6 hosts option to JSON and then
// unmarshaling it to a map[string]string. This is done because the
// k6 v0.42 changed Hosts from a map to types.NullHosts and doesn't
// expose the map anymore.
//
// TODO: A better way to do this would be to handle the resolver
// rules by communicating with Chromium (and then using Hosts's
// Match method) instead of passing the rules via the command line
// to Chromium.
var rules map[string]string
b, err := json.Marshal(k6opts.Hosts)
if err != nil {
return fmt.Errorf("marshaling hosts option: %w", err)
}
if err := json.Unmarshal(b, &rules); err != nil {
return fmt.Errorf("unmarshaling hosts option: %w", err)
}
for k, v := range rules {
hostResolver = append(hostResolver, fmt.Sprintf("MAP %s %s", k, v))
}
if len(hostResolver) > 0 {
sort.Strings(hostResolver)
flags["host-resolver-rules"] = strings.Join(hostResolver, ",")
}
return nil
}
// makeLogger makes and returns an extension wide logger.
func makeLogger(ctx context.Context, envLookup env.LookupFunc) (*log.Logger, error) {
var (
k6Logger = k6ext.GetVU(ctx).State().Logger
logger = log.New(k6Logger, common.GetIterationID(ctx))
)View on GitHub (pinned to 8d06114777)