JuliusBrussee/caveman · error
browser function threw
Error message
browser function threw
What it means
Thrown in callOnNodeRaw (browse/cdp.go) when the Runtime.callFunctionOn invocation succeeds at the protocol level but the browser reports an exception detail (e.g. the JS function itself threw). The Go wrapper surfaces this uniformly because protocol errors and JS exceptions arrive on different channels.
Solutions
- Inspect what the injected function does and wrap its body in try/catch returning a diagnostic string.
- Log/inspect fn (the generated JS) — validate it evaluates in the page console first.
- Re-snapshot and retry; the node may have been swapped for a different one mid-call.
- Verify the target realm/frame matches where the element lives.
Defensive patterns
Strategy: try-catch
Validate before calling
if !jsFunctionSyntaxValid(fn) { return fmt.Errorf("generated JS invalid") } Try / catch
out, err := sess.CallOnNode(target, fn)
var jsErr *browserJSError
if errors.As(err, &jsErr) {
log.Printf("page-side throw in fn %q: %v", fnName, err)
return fallbackValue
}
return err Prevention
- Test the injected JS in the browser console against representative pages.
- Wrap generated function bodies defensively (optional chaining, typeof checks).
- Build fn via json.Marshal (jsString) instead of string concatenation.
- Pin browser and chromedp versions tested against your scripts.
When it happens
Trigger: Any callOnNode/callBoolOnNode whose injected JS function throws in page context: referencing undefined properties, syntax errors in the generated function body, SecurityError/CORS restrictions, or calling methods absent in the page's runtime.
Common situations: Selector matched an element in a different realm (iframe); site CSP or extension wrapping throws; JS built with expectations about a page API that the current page version lacks; JSON string interpolation via jsString produced invalid JS.
Related errors
- browser function returned no result object
- element not actionable: last box=%+v
- option not found
- resolve node returned no object
- start browser
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/a12b3b29913171e5.
Report an issue: GitHub.
Appendix: source
Thrown at browse/cdp.go:415
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)
}
func DefaultUserDataDir(home string) string {
if home == "" {
if h, err := os.UserHomeDir(); err == nil {
home = filepath.Join(h, ".caveman")
}
}View on GitHub (pinned to 3ee70a1026)