JuliusBrussee/caveman · error
resolve node returned no object
Error message
resolve node returned no object
What it means
Thrown in browse/cdp.go when DOM.resolveNode (via chromedp) completes without error but returns a nil RemoteObject for the target's backend DOM node ID. The library needs a Runtime object handle to call JS functions on the node, so a nil object means the browser could not materialize the node. It is treated as a hard failure rather than silently producing a nil call target.
Solutions
- Re-snapshot the page to get a fresh target/handle, then retry the call on the new node.
- Check the element still exists before calling (e.g. presence query) and skip detached nodes.
- Ensure no navigation or heavy DOM mutation happens between snapshot and node call; await stability first.
- If reproducible on iframes, re-resolve within the correct frame's context.
Example fix
// before
target, _ := snap.Targets()["#btn"]
out, err := sess.CallOnNode(target, fn)
// after
snap, err := sess.Refresh() // re-snapshot after DOM changed
target, ok := snap.Targets()["#btn"]
if !ok { return errors.New("node gone; re-snapshot") }
out, err := sess.CallOnNode(target, fn) Defensive patterns
Strategy: retry
Try / catch
out, err := sess.CallOnNode(target, fn)
if err != nil && strings.Contains(err.Error(), "resolve node returned no object") {
snap, rerr := sess.Refresh()
if rerr != nil { return rerr }
t, ok := snap.Targets()[sel]
if !ok { return fmt.Errorf("node %s gone", sel) }
out, err = sess.CallOnNode(t, fn)
}
return err Prevention
- Re-snapshot immediately before interacting with elements on dynamic pages.
- Wait for network/DOM idle after navigation before capturing targets.
- Avoid caching target handles across navigation or re-renders.
- Check element presence before calling functions on it.
When it happens
Trigger: Calling callOnNode/callBoolOnNode on a target whose BackendDOMNodeID is stale: the DOM node was removed or the frame navigated between target capture and the resolveNode CDP call, so the browser returns no object for that backend node ID.
Common situations: Page re-rendered or element detached after a snapshot was taken; SPA navigation replaced the DOM; iframe content removed; running the CDP call against a frame whose execution context is gone.
Related errors
- option not found
- browser function returned no result object
- browser function threw
- element not actionable: last box=%+v
- missing backend DOM node id
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/fba860a5a619da17.
Report an issue: GitHub.
Appendix: source
Thrown at browse/cdp.go:407
if err := json.Unmarshal(res.Value, &out); err != nil {
return false, err
}
return out, nil
}
func (d *CDPDriver) callOnNodeRaw(ctx context.Context, target Target, fn string) (*runtime.RemoteObject, error) {
if target.BackendDOMNodeID <= 0 {
return nil, errors.New("missing backend DOM node id")
}
var res *runtime.RemoteObject
var exception *runtime.ExceptionDetails
if err := chromedp.Run(ctx, chromedp.ActionFunc(func(actionCtx context.Context) error {
obj, err := dom.ResolveNode().WithBackendNodeID(cdp.BackendNodeID(target.BackendDOMNodeID)).Do(actionCtx)
if err != nil {
return err
}
if obj == nil {
return errors.New("resolve node returned no object")
}
res, exception, err = runtime.CallFunctionOn(fn).WithObjectID(obj.ObjectID).Do(actionCtx)
return err
})); err != nil {
return nil, err
}
if exception != nil {
return nil, errors.New("browser function threw")
}
if res == nil {
return nil, errors.New("browser function returned no result object")
}
return res, nil
}
func jsString(s string) string {
b, _ := json.Marshal(s)
return string(b)View on GitHub (pinned to 3ee70a1026)