Skip to main content

Confirm

Are you sure?

Guide

How to find JavaScript errors on a site you don't control

A client's site, a competitor's checkout, a page your tag manager touches: you can't add an error tracker to it, but you can still see what breaks. Here's how, and what each method misses.

By · Last updated: September 2026

TL;DR

To find JavaScript errors on a site you don't control, load it in a browser and listen to the console: by hand in DevTools, or from code with headless Chrome capturing console.error, console.warn, uncaught exceptions and unhandled promise rejections. A load-time capture catches what breaks on arrival; errors behind a click or a login need a script that performs them, or real-user monitoring.

Free plan, no credit card. 1,000 credits a month.

The premise

Every JavaScript error happens in a browser you can own

Error trackers like Sentry need a snippet on the site. A client's site, a vendor's checkout or a page your tag manager touches won't let you add one. You don't need it: the errors happen in the visitor's browser, and you can be the visitor.

Load the page in a browser you control and listen to its console, and you see what any visitor would see — the errors the page's own code logs, and the exceptions nothing caught. That works on any public page, needs no access to the code, and leaves no trace on the site.

What it can't see is anything that doesn't run in that one visit: server-side errors, code paths behind a login or a click you didn't make, and the long tail of browsers and extensions your real visitors bring. Keep that boundary in mind; it decides which method below fits.

By hand

Method 1: DevTools, for one page right now

  1. 1
    Open the page in Chrome, then DevTools: F12, or Cmd+Option+J on a Mac to land on the Console.
  2. 2
    Tick Preserve log so messages survive redirects, then reload — errors during load are the ones you most want, and they happen before you opened the panel.
  3. 3
    Filter to Errors and Warnings. Click a message's source link to jump to the line; if the file is minified, the {} button pretty-prints it.
  4. 4
    Check the Network panel too, filtered to failed requests. A blocked script or a 404ed chunk is often the cause of the error you're reading.

It's the fastest way to understand one error. It doesn't scale past a handful of pages, and it only tells you about today.

From code

Method 2: capture the console with headless Chrome

Automate the same thing and you can check hundreds of pages, on a schedule, and diff the results. Two events matter: console messages at the error and warning level, and uncaught exceptions, which Puppeteer calls pageerror.

Puppeteer: collect errors and uncaught exceptions during load
import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const page = await browser.newPage();
const messages = [];

page.on("console", (msg) => {
  if (["error", "warn"].includes(msg.type())) messages.push({ type: msg.type(), text: msg.text() });
});
page.on("pageerror", (err) => messages.push({ type: "exception", text: err.message }));

await page.goto("https://example.com", { waitUntil: "networkidle2", timeout: 30_000 });
await new Promise((r) => setTimeout(r, 2000)); // let late scripts report
console.log(JSON.stringify(messages, null, 2));
await browser.close();

Two practical notes. Chrome logs some messages itself — a failed resource load, a mixed-content or CSP violation — which arrive through the same console event; decide whether you want those or only what the page's code logged. And networkidle2 plus a short wait is a compromise: errors from scripts that run on a timer, or after the first interaction, need longer or a scripted interaction to appear.

Reading the output

What you'll see, and what's worth fixing

KindLooks likeUsually means
Uncaught exceptionTypeError: Cannot read properties of undefinedCode that broke. Something on the page probably doesn't work.
Unhandled promise rejectionUncaught (in promise) Error: Request failedA failed fetch or async step nobody handled — often missing content.
console.error from the pageHydration failed because the server HTML didn't matchThe code noticed a problem and said so. Read it; it's often specific.
console.warnDeprecated API, cookie attribute, third-party noticeRarely urgent; watch for new ones.
Third-party noiseErrors from an ad, analytics or chat scriptNot your bug, but it can still break your page.
  • Load the page more than once. Ads, A/B tests and consent state vary per visit, and race conditions fail intermittently. An error in three of three loads is a bug; one in five may be a third party.
  • Group by message, not by occurrence. Strip numbers and ids from messages and count distinct ones — fifty pages with the same error is one fix.
  • Diff against yesterday. For monitoring, the useful signal is a message that wasn't there before a deploy, not the steady background.
  • Minified names are normal. t is not a function on a site without public source maps is as specific as it gets from outside; the page and the timing are your clues.

Limits

What a load-time capture misses

  • Errors behind interactions. A broken "Add to cart" throws when clicked. Capture it with a scripted flow — Playwright can click, type and assert — or with real-user monitoring on your own site.
  • Errors behind a login. An anonymous visit sees the anonymous page.
  • Other browsers. Headless Chrome finds Chrome's errors. Safari-only failures need WebKit, which Playwright can drive.
  • Embedded frames. An ad or a video player in an iframe logs to its own console. Most capture setups only listen to the top page, which is usually what you want — but it means a broken embed can be invisible.
  • Server errors. A 500 from an API shows up only if the page's code reacts to it.

With URLpipe

The console of any page, as JSON

URLpipe's JavaScript error checker and the /console endpoint run Method 2 for you. They load the page in real Chrome, record console.error, console.warn, uncaught exceptions and unhandled promise rejections, wait briefly after the network settles so late scripts can report, and return them as a JSON array of {type, text} — an empty array when the page is clean. It costs 1 credit a page.

To be precise about the boundaries: it records what the page's code logs or throws, not console.log, and not the messages Chrome itself writes about failed resource loads — check those with the rendered HTML and your own network tooling. It listens to the top page, not to embedded frames. And for errors that arrive on a timer, page_options.delay waits up to 10 more seconds; see page options.

POST /console
curl -X POST https://urlpipe.dev/console \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/checkout", "sync": true, "page_options": {"delay": 3000}}'

# e.g. [{"type": "exception", "text": "Uncaught TypeError: Cannot read properties of undefined (reading 'price')"}]

Run it on a schedule over your clients' key pages, store the results, and alert on new messages — that's a JavaScript error monitor for sites you don't control, in a cron job.

FAQ

Frequently asked questions

How do I see JavaScript errors on a website?
Open DevTools (F12, or Cmd+Option+J on a Mac), go to the Console tab and reload the page. Errors appear in red, warnings in yellow. To do it for many pages or on a schedule, capture the console from a headless browser instead.
Can I find errors on a site without access to its code?
Yes. Every error a page throws happens in the visitor's browser, so any browser you control can observe it. You can't see server-side errors, and you only see what the pages you load actually run.
What's the difference between an error and an exception in the console?
An error or warning is something the page's code chose to log with console.error or console.warn. An uncaught exception is a failure nothing handled — a TypeError, a ReferenceError, a rejected promise — and is usually the more serious of the two.
Why do I see different errors each time I load the page?
Third-party scripts — ads, analytics, A/B tests, chat widgets — vary by visit, region and consent state, and timing-dependent code fails intermittently. Capture several loads and look for the errors that repeat.
Does a console capture catch failed network requests?
Not necessarily. A request that fails appears in the Network panel; it only reaches the console if the page's code logs it or throws because of it. Check the Network panel, or a HAR file, for 404s and blocked requests.

Put this into practice.

Each of the eight kinds of data URLpipe returns has a free, no-signup tool — try the ideas from this guide on a real page, then grab an API key to run them from your code. 1,000 credits a month, no card.