grafana/k6 · warning

disposing element handle: %w

Error message

disposing element handle: %w

What it means

In ElementHandle.Query(), when the queried handle turns out not to be an element, a deferred Dispose() of that useless handle failed and its error is joined onto the return error (element_handle.go:1239). The dispose failure itself is secondary — the primary problem is the accompanying 'querying selector' error; dispose fails when the session/target is already gone.

Source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:1239

		forceCallable: true,
		returnByValue: false,
	}
	result, err := h.evalWithScript(h.ctx, opts, querySelector, parsedSelector, strict)
	if err != nil {
		return nil, fmt.Errorf("querying selector %q: %w", selector, err)
	}
	if result == nil {
		return nil, nil //nolint:nilnil
	}
	handle, ok := result.(JSHandleAPI)
	if !ok {
		return nil, fmt.Errorf("querying selector %q, wrong type %T", selector, result)
	}
	element := handle.AsElement()
	if element == nil {
		defer func() {
			if err := handle.Dispose(); err != nil {
				err = fmt.Errorf("disposing element handle: %w", err)
				rerr = errors.Join(err, rerr)
			}
		}()
		return nil, fmt.Errorf("querying selector %q", selector)
	}

	return element, nil
}

// QueryAll queries element subtree for matching elements.
// If no element matches the selector, the return value resolves to "null".
func (h *ElementHandle) QueryAll(selector string) ([]*ElementHandle, error) {
	handles, err := h.queryAll(selector, h.evalWithScript)
	if err != nil {
		return nil, fmt.Errorf("querying all selector %q: %w", selector, err)
	}

	return handles, nil

View on GitHub (pinned to 93accf6570)

Solutions

  1. Fix the primary error first (see 'querying selector ...') — this error only rides along
  2. Make sure no navigation/close happens while browser promises are pending
  3. If the target is already closed, this error can be safely ignored in logs
  4. Upgrade k6; dispose-after-close handling has been improved over releases
Defensive patterns

Strategy: try-catch

Try / catch

try { const child = await el.$(sel); }
catch (e) { /* primary 'querying selector' error is the actionable one; ignore joined dispose error if target closed */ if (!/disposing element handle/.test(e.message)) throw e; }

Prevention

When it happens

Trigger: The result handle is a non-element node AND the browser target, page, or execution context was destroyed before the cleanup Dispose ran (navigation or close during the call).

Common situations: End-of-iteration cleanup races: k6 closes the browser while a query is finishing; the joined error adds noise on top of the real failure.

Related errors


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