grafana/k6 · warning
already belongs to the same execution context
Error message
already belongs to the same execution context
What it means
ExecutionContext.adoptElementHandle (execution_context.go:106-141) re-creates an ElementHandle inside a different execution context by resolving its backend node. If the handle's context is already this exact context (eh.execCtx == e), adoption is pointless and the method refuses with this error rather than silently no-opping.
Source
Thrown at internal/js/modules/k6/browser/common/execution_context.go:138
func (e *ExecutionContext) adoptElementHandle(eh *ElementHandle) (*ElementHandle, error) {
var (
efid cdp.FrameID
esid target.SessionID
)
if eh.frame != nil {
efid = cdp.FrameID(eh.frame.ID())
}
if eh.session != nil {
esid = eh.session.ID()
}
e.logger.Debugf(
"ExecutionContext:adoptElementHandle",
"sid:%s stid:%s fid:%s ectxid:%d furl:%q ehtid:%s ehsid:%s",
e.sid, e.stid, e.fid, e.id, e.furl,
efid, esid)
if eh.execCtx == e {
return nil, errors.New("already belongs to the same execution context")
}
if e.frame == nil {
return nil, errors.New("does not have a frame owner")
}
var node *cdp.Node
var err error
action := dom.DescribeNode().WithObjectID(eh.remoteObject.ObjectID)
if node, err = action.Do(cdp.WithExecutor(e.ctx, e.session)); err != nil {
return nil, fmt.Errorf("describing DOM node: %w", err)
}
return e.adoptBackendNodeID(node.BackendNodeID)
}
// eval evaluates the provided JavaScript within this execution context and
// returns a value or handle.View on GitHub (pinned to 01ffac6f24)
Solutions
- If you control the call path, compare the handle's owning context/frame before adopting and skip when they already match
- Re-query the element in the target frame instead of adopting an existing handle
- Dispose the old handle and use page.$/frame.$ on the current frame to get a handle in the right context
- Upgrade k6: internal waitForSelector logic (frame.go:513) already checks worlds, so newer builds narrow this race
Defensive patterns
Strategy: try-catch
Try / catch
try {
adopted = await targetFrame.adoptElementHandle(handle);
} catch (e) {
if (/already belongs/.test(e.message)) {
adopted = handle; // already in the right context; just use it
} else throw e;
} Prevention
- Compare the handle's owning frame/context before adopting (the library does this in waitForSelector)
- Prefer re-querying elements on the target frame over adopting existing handles
- Treat 'already belongs' as a no-op condition, not a failure
When it happens
Trigger: Calling adoption paths where source and target context are identical. User scripts rarely call this directly; it is reachable via frame/frameElement flows and waitForSelector's adoption step (frame.go:513-521), which guards it by comparing worlds first — so hitting it usually means an internal race during navigation reassigned the handle's context.
Common situations: Surfaces as an inner error inside waitForSelector/frame operations during rapid navigation when a handle's world flipped between the check and the adoption; mostly seen in k6 logs rather than as the primary script error.
Related errors
- Unexpected end of selector while parsing selector `${selecto
- does not have a frame owner
- on create page event failed to return a page: %w
- checking state %q of element %q
- unexpected type %T
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/e7e9b41a86f65ead.
Report an issue: GitHub.