{"record":{"id":"e7e9b41a86f65ead","repo":"grafana/k6","slug":"already-belongs-to-the-same-execution-context","errorCode":null,"errorMessage":"already belongs to the same execution context","messagePattern":"already belongs to the same execution context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/js/modules/k6/browser/common/execution_context.go","lineNumber":138,"sourceCode":"func (e *ExecutionContext) adoptElementHandle(eh *ElementHandle) (*ElementHandle, error) {\n\tvar (\n\t\tefid cdp.FrameID\n\t\tesid target.SessionID\n\t)\n\tif eh.frame != nil {\n\t\tefid = cdp.FrameID(eh.frame.ID())\n\t}\n\tif eh.session != nil {\n\t\tesid = eh.session.ID()\n\t}\n\te.logger.Debugf(\n\t\t\"ExecutionContext:adoptElementHandle\",\n\t\t\"sid:%s stid:%s fid:%s ectxid:%d furl:%q ehtid:%s ehsid:%s\",\n\t\te.sid, e.stid, e.fid, e.id, e.furl,\n\t\tefid, esid)\n\n\tif eh.execCtx == e {\n\t\treturn nil, errors.New(\"already belongs to the same execution context\")\n\t}\n\tif e.frame == nil {\n\t\treturn nil, errors.New(\"does not have a frame owner\")\n\t}\n\n\tvar node *cdp.Node\n\tvar err error\n\n\taction := dom.DescribeNode().WithObjectID(eh.remoteObject.ObjectID)\n\tif node, err = action.Do(cdp.WithExecutor(e.ctx, e.session)); err != nil {\n\t\treturn nil, fmt.Errorf(\"describing DOM node: %w\", err)\n\t}\n\n\treturn e.adoptBackendNodeID(node.BackendNodeID)\n}\n\n// eval evaluates the provided JavaScript within this execution context and\n// returns a value or handle.","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/common/execution_context.go#L120-L156","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  adopted = await targetFrame.adoptElementHandle(handle);\n} catch (e) {\n  if (/already belongs/.test(e.message)) {\n    adopted = handle; // already in the right context; just use it\n  } else throw e;\n}","preventionTips":["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"],"tags":["browser","execution-context","internal","adoption"],"backgroundTag":"execution-context-mismatch","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}