JuliusBrussee/caveman · error
resolve node returned no object
Error message
resolve node returned no object
What it means
Returned inside callOnNodeRaw's chromedp action when dom.ResolveNode().WithBackendNodeID(...) succeeds without error but returns a nil remote object. ResolveNode should produce a RemoteObject for the node's JS wrapper; nil means Chrome could not produce one (node in a destroyed context, or backend id no longer valid even though the call did not error), so there is no ObjectID to CallFunctionOn with and the driver aborts.
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 27d5a3981a)
Solutions
- Take a new snapshot and use its uids — the old node handle is no longer resolvable.
- If it recurs on a live-looking element, the element is being replaced faster than you act; wait for a stable state (network idle, settled DOM) before snapshot+act.
- Prefer re-acquiring over retrying the same handle; the nil object will not self-heal.
Defensive patterns
Strategy: try-catch
Try / catch
// Go
obj, err := dom.ResolveNode().WithBackendNodeID(id).Do(ctx)
if err != nil {
return err
}
if obj == nil {
// node's JS wrapper is gone: re-snapshot to acquire a fresh handle
return errStaleHandle{id: id}
} Prevention
- Treat resolve-node nil as 'stale handle': re-snapshot, never retry the same id.
- Wait for settled DOM (no pending mutations/navigations) before acting on freshly-queried nodes.
- Avoid acting on nodes inside frames mid-swap; site isolation makes their handles short-lived.
When it happens
Trigger: Evaluating a function on a node whose backing JS object is gone: after navigation destroyed the frame, the node was removed from the document, or the backend id references a node in a swapped-out frame.
Common situations: Acting on a uid captured before an SPA transition; deferred actions on nodes a script has since replaced; cross-origin iframe nodes whose process was swapped.
Related errors
- missing backend DOM node id
- select: missing option
- box model has no quad
- browser returned no result object
- browser function threw
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/fba860a5a619da17.
Report an issue: GitHub.