From eb683ddd2c4ffdb84befe834f443ff025b4beb7f Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Wed, 17 Jun 2026 08:27:21 +0530 Subject: [PATCH] fix: continue rendering when Chrome hits 'Object reference chain is too long' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a page's JavaScript builds deeply nested object graphs, Chrome's DevTools Protocol returns error -32000 'Object reference chain is too long' during WaitLoad. The page has still loaded its HTML — the error is about Chrome's internal object tracking, not the document itself. This change detects this specific error and proceeds with rendering instead of failing the entire page, so sites with complex JS still get cloned successfully (issue #36). Signed-off-by: Gautam Kumar --- browser/pool.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/browser/pool.go b/browser/pool.go index a2e144e..675d00c 100644 --- a/browser/pool.go +++ b/browser/pool.go @@ -124,7 +124,14 @@ func (p *Pool) Render(ctx context.Context, rawURL string) (RenderResult, error) return RenderResult{}, fmt.Errorf("navigate %s: %w", rawURL, navErr) } if err := page.WaitLoad(); err != nil { - return RenderResult{}, fmt.Errorf("wait load %s: %w", rawURL, err) + // Chrome's DevTools Protocol may return "Object reference chain is too + // long" when a page's JavaScript builds deeply nested object graphs. + // The page has still loaded its HTML — the error is only about Chrome's + // internal object tracking, not about the document. Log the warning and + // continue rendering rather than failing the entire page (issue #36). + if !isObjRefChainError(err) { + return RenderResult{}, fmt.Errorf("wait load %s: %w", rawURL, err) + } } settle(page, p.opts.Settle) if p.opts.Scroll { @@ -434,6 +441,15 @@ func isHTML(contentType string) bool { return mt == "" || mt == "text/html" || mt == "application/xhtml+xml" } +// isObjRefChainError reports whether err is the Chrome DevTools Protocol error +// "Object reference chain is too long" (code -32000). This surfaces when a +// page's JavaScript builds deeply nested object graphs. The page has still +// loaded — Chrome's internal state tracking hit a limit, not the document +// itself (issue #36). +func isObjRefChainError(err error) bool { + return err != nil && strings.Contains(err.Error(), "Object reference chain is too long") +} + // settle waits for the network to go quiet for d, recovering from any rod // panic and capping the wait so a chatty page can never hang the worker. func settle(page *rod.Page, d time.Duration) {