JuliusBrussee/caveman · error

browser function returned no result object

Error message

browser function returned no result object

What it means

Returned by callOnNodeRaw() when runtime.CallFunctionOn completes without error and without an exception but yields a nil result RemoteObject. Distinct from 'browser function threw' (exception present) and from decodeBoolObject's 'browser returned no result object' (higher up); here the raw evaluation path got nothing back, which happens when the function returns undefined or the context is torn down around the call. The driver fails closed rather than nil-deref.

Source

Thrown at browse/cdp.go:418

	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")
		}
	}
	if home == "" {
		return ""
	}

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Make the injected function explicitly return a value (return document.activeElement !== this; not just the comparison as a statement body that gets dropped).
  2. If the function already returns, re-snapshot and retry once — a torn-down context can swallow results.
  3. Test the function body standalone via eval on the same node to confirm it produces a value.

Example fix

// before — function body has no return
`function(){ this.focus(); }`

// after
`function(){ this.focus(); return document.activeElement === this; }`
Defensive patterns

Strategy: type-guard

Validate before calling

// Go: when writing injected functions, always return a value
// bad:  function(){ this.focus(); }
// good: function(){ this.focus(); return document.activeElement === this; }

Type guard

func hasResult(res *runtime.RemoteObject) (*runtime.RemoteObject, error) {
    if res == nil {
        return nil, errors.New("browser function returned no result object")
    }
    return res, nil
}

Try / catch

// Go
res, err := d.callOnNodeRaw(ctx, target, fn)
if err != nil {
    if strings.Contains(err.Error(), "returned no result object") {
        // likely undefined return: fix fn to return, then one retry after re-snapshot
        return fixFnAndRetry(ctx, target, fn)
    }
    return nil, err
}

Prevention

When it happens

Trigger: An on-node evaluation whose function implicitly returns undefined (missing return statement), or a call racing context destruction so Chrome drops the result silently.

Common situations: Custom probe functions written as statements instead of expressions forgetting to return; eval helpers reused from console (where undefined results are normal) pasted into act paths; navigation racing the eval.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/e7706afabe3657ac. Report an issue: GitHub.