grafana/k6 · error

attaching worker target ID %v to session ID %v: %w

Error message

attaching worker target ID %v to session ID %v: %w

What it means

k6 automatically attaches to every CDP target a page creates, including web and service workers. attachWorkerToTarget builds a Worker via NewWorker, which enables Log, Network and Runtime domains on the worker's session (worker.go initEvents). This error means that protocol initialization failed, and the failure is wrapped with the worker target ID and session ID. It usually indicates the worker target died between attach and init, or the page/context was closing (fs.ctx canceled).

Source

Thrown at internal/js/modules/k6/browser/common/frame_session.go:1082

		}
		return err
	}

	return nil
}

// attachWorkerToTarget attaches a Worker target to a given session.
func (fs *FrameSession) attachWorkerToTarget(ti *target.Info, session *Session) error {
	if fs.page.isClosing() {
		fs.logger.Debugf("FrameSession:attachWorkerToTarget",
			"rejected worker; page is closing: tid=%v", ti.TargetID)
		detachSession(fs.teardownCtx, session)
		return nil
	}

	w, err := NewWorker(fs.ctx, session, ti.TargetID, ti.URL)
	if err != nil {
		return fmt.Errorf("attaching worker target ID %v to session ID %v: %w",
			ti.TargetID, session.ID(), err)
	}
	fs.page.addWorker(session.ID(), w)

	return nil
}

func (fs *FrameSession) onDetachedFromTarget(event *target.EventDetachedFromTarget) {
	fs.logger.Debugf("FrameSession:onDetachedFromTarget",
		"sid:%v tid:%v esid:%v",
		fs.session.ID(), fs.targetID, event.SessionID)

	fs.page.removeWorker(event.SessionID)
}

func (fs *FrameSession) onTargetCrashed() {
	fs.logger.Debugf("FrameSession:onTargetCrashed", "sid:%v tid:%v", fs.session.ID(), fs.targetID)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Keep the page and browser context open until workers have fully loaded; avoid closing while the application spawns workers
  2. Re-run the iteration: this is frequently a race between worker creation and teardown and does not reproduce consistently
  3. Check k6/browser logs for the underlying 'protocol error while initializing worker' cause and fix that first (crashed browser, out of memory, disconnected DevTools connection)
  4. Upgrade k6 to a recent release: worker and session lifecycle handling has been hardened over time

Example fix

// before: context torn down while app spawns workers
await page.goto('https://app.example.com');
await context.close(); // workers still starting

// after: let workers settle before teardown
await page.goto('https://app.example.com');
await page.waitForTimeout(2000); // or wait for an app-ready signal
await context.close();
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await page.goto(workerHeavyUrl);
} catch (e) {
  if (/attaching worker target ID/.test(String(e.message))) {
    // worker raced teardown or worker target died; retry iteration or ignore
  } else { throw e; }
}

Prevention

When it happens

Trigger: The page under test spawns a Web Worker (new Worker(...)), SharedWorker or service worker; the browser emits Target.attachedToTarget; NewWorker runs log.Enable/network.Enable/RunIfWaitingForDebugger on the worker session and one of those CDP commands fails because the worker terminated immediately, the session is invalid, or fs.ctx is canceled during page/context teardown.

Common situations: Testing sites that offload work to workers or register service workers; worker creation racing page.close() or browserContext.close(); short-lived workers (spawn, postMessage, terminate) that finish before k6 finishes attaching; browser crash or OOM mid-run.

Related errors


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