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

  1. Re-snapshot the page to get a fresh target/handle, then retry the call on the new node.
  2. Check the element still exists before calling (e.g. presence query) and skip detached nodes.
  3. Ensure no navigation or heavy DOM mutation happens between snapshot and node call; await stability first.
  4. 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

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


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)