JuliusBrussee/caveman · error

missing backend DOM node id

Error message

missing backend DOM node id

What it means

CDPDriver.box computes an element's bounding box by querying the DOM box model for a backend DOM node ID. If the Target carries no positive BackendDOMNodeID there is nothing to query, so box fails immediately with 'missing backend DOM node id' instead of issuing a doomed dom.GetBoxModel call.

Solutions

  1. Re-resolve the element to obtain a fresh backend DOM node id before calling actionable/box operations
  2. Fix the code path that constructed the Target so it always populates BackendDOMNodeID from a successful dom query
  3. Invalidate cached Targets after navigation or DOM mutation and re-query
  4. Add an upstream check that BackendDOMNodeID > 0 before queuing actions on a Target

Example fix

// before
target := Target{} // BackendDOMNodeID == 0
// after
target, err := d.resolve(selector)
if err != nil { return err } // target.BackendDOMNodeID > 0
Defensive patterns

Strategy: validation

Validate before calling

func (t Target) readyForGeometry() bool {
    return t.BackendDOMNodeID > 0
}

Type guard

func usableTarget(t Target) bool {
    return t.BackendDOMNodeID > 0
}

if !usableTarget(t) {
    t, err = d.resolve(selector)
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling box (indirectly via waitActionable) with a Target whose BackendDOMNodeID is 0 or negative — typically a Target constructed locally or defaulted rather than one obtained from a real DOM resolve/query in the page.

Common situations: A caller cached a Target across page navigations and the node id is stale/zero; a code path built a Target struct literal without running the node-discovery step; the element lookup failed upstream and an empty Target was propagated; serialization of a Target dropped the id field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/c03da071330aa43c. Report an issue: GitHub.

Appendix: source

Thrown at browse/cdp.go:303

		}
		select {
		case <-ctx.Done():
			return 0, 0, ctx.Err()
		case <-time.After(100 * time.Millisecond):
		}
	}
}

type boxPoint struct {
	x float64
	y float64
	w float64
	h float64
}

func (d *CDPDriver) box(ctx context.Context, target Target) (float64, float64, float64, float64, error) {
	if target.BackendDOMNodeID <= 0 {
		return 0, 0, 0, 0, errors.New("missing backend DOM node id")
	}
	var model *dom.BoxModel
	if err := chromedp.Run(ctx, chromedp.ActionFunc(func(actionCtx context.Context) error {
		var err error
		model, err = dom.GetBoxModel().WithBackendNodeID(cdp.BackendNodeID(target.BackendDOMNodeID)).Do(actionCtx)
		return err
	})); err != nil {
		return 0, 0, 0, 0, err
	}
	quad := model.Content
	if len(quad) < 8 {
		quad = model.Border
	}
	if len(quad) < 8 {
		return 0, 0, 0, 0, errors.New("box model has no quad")
	}
	minX, maxX := quad[0], quad[0]
	minY, maxY := quad[1], quad[1]

View on GitHub (pinned to 3ee70a1026)