grafana/k6 · error

options: unsupported type %T

Error message

options: unsupported type %T

What it means

Thrown by ConvertSelectOptionValues when the selectOption values argument's exported kind matches none of the accepted cases: slice (array), map (plain object), *common.ElementHandle (an <option> element handle), or string. Numbers, booleans, functions, undefined-carrying slots, and any other kind reject with 'options: unsupported type <type>', wrapped by the mapping as 'parsing select option values: ...'.

Source

Thrown at internal/js/modules/k6/browser/browser/mapping.go:125

				*opt.Value = obj.Get(k).String()
			case "label":
				opt.Label = new(string)
				*opt.Label = obj.Get(k).String()
			case "index":
				opt.Index = new(int64)
				*opt.Index = obj.Get(k).ToInteger()
			}
		}
		opts = append(opts, &opt)
	case reflect.String:
		// Strings will match values or labels
		valOpt := common.SelectOption{Value: new(string)}
		*valOpt.Value = t.(string) //nolint:forcetypeassert
		labelOpt := common.SelectOption{Label: new(string)}
		*labelOpt.Label = t.(string) //nolint:forcetypeassert
		opts = append(opts, &valOpt, &labelOpt)
	default:
		return nil, fmt.Errorf("options: unsupported type %T", values)
	}

	return opts, nil
}

func extractSelectOptionFromMap(v map[string]any) (*common.SelectOption, error) {
	opt := &common.SelectOption{}
	for k, raw := range v {
		switch k {
		case "value":
			opt.Value = new(string)

			v, ok := raw.(string)
			if !ok {
				return nil, fmt.Errorf("options[%v]: expected string, got %T", k, raw)
			}

			*opt.Value = v

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use a descriptor for numeric selection: selectOption({ index: 2 })
  2. Use a string for value/label matching: selectOption('red')
  3. Pass null or undefined to express 'no selection', never false/0
  4. Type-check dynamic values before the call and normalize them to string or descriptor

Example fix

// before
await page.locator('select.qty').selectOption(3);

// after
await page.locator('select.qty').selectOption({ index: 3 });
Defensive patterns

Strategy: type-guard

Validate before calling

function assertSelectValuesKind(values) {
  if (values === null || values === undefined) return; // allowed: no selection
  const t = typeof values;
  if (t === 'string' || t === 'object') return; // string, array, plain object, ElementHandle
  throw new TypeError(`selectOption values of type ${t} are not supported; use a string, {index:n}, or null`);
}

Type guard

function isSelectOptionValues(v) {
  if (v === null || v === undefined || typeof v === 'string') return true;
  if (typeof v !== 'object') return false; // numbers, booleans, functions rejected
  if (Array.isArray(v)) return v.every((it) => typeof it === 'string' || (typeof it === 'object' && it !== null));
  return true; // plain object descriptor or ElementHandle-like
}

Try / catch

try {
  await locator.selectOption(values, opts);
} catch (e) {
  if (/unsupported type/.test(String(e.message))) {
    throw new Error(`selectOption got an unsupported value (${typeof values}); wrap numbers as {index: n}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: selectOption(2) — raw numeric index; selectOption(true); selectOption(() => {}) — function value; selectOption(Symbol()) or other unsupported kinds.

Common situations: Passing option indices as bare numbers (very common when porting from frameworks that accept numeric indexes); dynamically computed values whose type is not pinned down; forgetting that null/undefined is the only 'empty' value allowed.

Related errors


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