---
title: "Fix the script error that hides its message, file, and line"
description: "Script error. with line 0 and no stack means the browser hid an error from a script on another origin. Add crossorigin and a CORS header to get the message back."
canonical: "https://logbrew.co/en/errors/script-error"
last_updated: "2026-11-10"
---

# Fix the script error that hides its message, file, and line

`Script error.` with line 0 and no stack means the browser hid an error from a script on another origin. Add `crossorigin` and a CORS header to get the message back.

Tested on November 10, 2026 with Chromium 152, @logbrew/browser 0.1.21, and @logbrew/sdk 0.1.44

By [Furkan Erday](https://github.com/furkanerday). Furkan Erday is the founder of LogBrew. He builds LogBrew with Claude Code and Codex every day.

Canonical: https://logbrew.co/en/errors/script-error

## What the page learns from a script that throws

| How the script loads | Script ran | Error details |
| --- | --- | --- |
| From the page's own origin | Ran | Full |
| From another origin | Ran | `Script error.` |
| Another origin, `crossorigin` and the CORS header | Ran | Full |
| Another origin, `crossorigin` and no header | Blocked | None |

1 script, loaded 4 ways. Full means the message, file, line 1, column 7, and the stack, read from the `error` event on `window`.

## Get the full error back

### Load the script with the crossorigin attribute

The attribute tells the browser to fetch the file with CORS. When the server allows it, the browser passes the real message, file, line, and stack to the page's error listeners.

```bash
<script src="https://cdn.example.com/app.js" crossorigin="anonymous"></script>
```

### Send the CORS header from the file's server

The server that hosts the script must answer with `Access-Control-Allow-Origin` set to your page's origin, or `*` for a public file. In our test, the header alone turned `Script error.` into the full message.

```bash
Access-Control-Allow-Origin: *
```

### Check that the file still loads

With `crossorigin` set and no header, the browser blocks the file and the script never runs. The console then shows `blocked by CORS policy` and `net::ERR_FAILED`, and the `script` element fires its `error` event.

Output

```text
Access to script at 'http://127.0.0.1:4874/plain/throws.js?scenario=script-cross-origin-attr-no-header' from origin 'http://127.0.0.1:4873' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Failed to load resource: net::ERR_FAILED
```

### Or serve the script from your own origin

A script from the page's own origin never mutes its errors. Bundle the file with your app, or proxy it through your domain, and no header is needed.

## Handle the muted errors you still get

### Count them, then find the script

`Script error.` carries nothing to fix. Each one means a script on another origin threw. Find the tags without `crossorigin` and start with the ones that load on every page.

### Read the real message in the console

The browser prints the full error to the console even when it mutes it for your listeners. In our test the console showed `Uncaught Error: Keg is empty` while `window.onerror` got `Script error.`.

### Decide what to do with third-party tags

A chat widget or analytics tag without a CORS header leaves you 2 choices. Keep it as it is and accept muted errors, or add `crossorigin` so a missing header blocks the tag and shows up as a failed load instead.

## What we saw when we tested it

We put 1 script that throws, `throw new Error("Keg is empty: no beer left for order 42");`, on 2 local servers. The page ran at `http://127.0.0.1:4873` in Chromium 152 with `@logbrew/browser` 0.1.21 installed, and a second server at `http://127.0.0.1:4874` played the CDN. We loaded the script 4 ways and read the `error` event on `window` each time.

From the page's own origin, the event carried `Uncaught Error: Keg is empty: no beer left for order 42`, the file `/throws.js`, line 1, column 7, and an `Error` object with a stack. From the other origin without `crossorigin`, the event carried `Script error.`, an empty file name, line 0, column 0, and no `Error` object. The console still printed the full message.

With `crossorigin="anonymous"` and `Access-Control-Allow-Origin: *` on the CDN, the event carried the full details again. With the attribute and no header, the browser blocked the file, the script never ran, and the `script` element fired its `error` event.

## Why the browser hides the message

The HTML Standard mutes errors from scripts the page fetched across origins without CORS. Its algorithm sets muted errors when the response was CORS-cross-origin, and then reports the error as `Script error.` with no URL, line 0, column 0, and no error object.

The browser treats the error text of a cross-origin script as that script's data, so the page gets none of it. MDN's page on `crossorigin` says the same in 1 line. Access to error logging through `window.onerror` is limited for such scripts.

whatwg/html#2440 asked for a way to get the details without CORS. It was closed in July 2024, on the day whatwg/html#10514 opened to report that browsers do not mute the same cases in the same way. That issue is still open.

## What LogBrew records

With the full details, the browser SDK sent 1 issue named `Browser error: Error` with a stack frame for `/throws.js` at line 1, column 7, the source path, and the grouping key `browser.error:Error:/throws.js`. Each script that throws gets its own issue.

With the muted error, the issue had the same name, no stack frames, line 0, column 0, and the grouping key `browser.error:Error`. Muted errors share that 1 issue, so its count tells you how many errors you cannot see yet.

Both events carried the page path, the runtime `Chromium 152` on `macOS`, and a `page_view` breadcrumb. Neither carried the message text. The SDK marked it `redacted`.

## Questions people ask

### What does Script error. mean in JavaScript?

A script from another origin threw an error, and the browser hid the details from the page because the file was not loaded with CORS. The script itself ran.

### Why does Script error. have line 0 and no stack?

The HTML Standard replaces the message, file, line, column, and error object when it mutes an error. Only the string `Script error.` is left.

### Does Script error. mean the script failed to load?

No. A script that fails to load fires the `error` event on its `script` element and never runs. `Script error.` means the script ran and threw.

### Can I see the message without changing the server?

In the browser console, yes. In your error tracking, no. The page needs `crossorigin` on the tag and the CORS header from the server, or the script on your own origin.

### Should I filter Script error. out of my error tracking?

Count it instead. The number tells you how many errors you cannot see, and it drops to 0 once every cross-origin script loads with CORS.

## Count the errors you cannot see yet

The LogBrew browser SDK keeps every muted error in 1 issue and gives each real one its file, line, and stack. Start on the generous free tier, no card needed.

[Start Free](https://logbrew.co/en)

## Sources

- [MDN, Window: error event](https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event)
- [MDN, crossorigin attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin)
- [HTML Standard, Runtime script errors](https://html.spec.whatwg.org/multipage/webappapis.html#runtime-script-errors)
- [whatwg/html#2440](https://github.com/whatwg/html/issues/2440)
- [whatwg/html#10514](https://github.com/whatwg/html/issues/10514)

## More JavaScript error fixes

- [Fix the Failed to fetch error and tell its 3 causes apart](https://logbrew.co/en/errors/failed-to-fetch)
- [JavaScript errors we reproduced, and how to fix each one](https://logbrew.co/en/errors)
