Why Is My JavaScript Not Working? Common Errors and Fixes
"My JavaScript isn't working" can describe a dozen different situations: a button that does nothing when clicked, a script that never seems to load, a form that submits the wrong data, or a page that looks fine until you open the console and see a wall of red text. Unlike HTML, which quietly does something not quite right and keeps going anyway, JavaScript usually gives you a direct, specific reason for what went wrong, if you know where to look. This guide covers the real difference between a script that crashed and one that's just producing the wrong result, walks through a complete working example with the kind of bugs that actually show up in everyday code, and shows exactly how to open your browser's console and read what it's telling you.
Quick Answer
Unlike a broken HTML page, JavaScript that isn't working almost always means the script hit an actual error and stopped running, whether or not you can see it happen. The console in your browser's developer tools shows that error directly, including the exact file and line number involved. Most "JavaScript not working" problems come down to one of a few causes: the script ran before the page's elements existed, a typo in a variable, function, or event name, a script file that failed to load, or, less obviously, a logic bug that produces the wrong result without throwing any error at all.
JavaScript Does Not Fail the Way HTML Does
A companion guide on this site explains why is my HTML not working, and the short version is that HTML never really stops. Browsers rewrite broken markup into something valid and keep rendering no matter what.
JavaScript works nothing like that. It is a real programming language with an actual grammar, and the browser's JavaScript engine enforces that grammar strictly. The moment the engine hits a line it cannot execute, whether that's a typo in a variable name or an attempt to call a method that doesn't exist, it throws an error and stops running the rest of that script block right there. Everything after the broken line simply never runs, even if it has nothing to do with the actual bug.
That single fact explains most "nothing happens when I click the button" reports. It's rarely that the button itself is broken. It's usually that an earlier line in the same script already failed, so the code that would have attached the click handler never ran at all.
Not every JavaScript problem announces itself this loudly, though. Plenty of bugs produce a wrong result without throwing anything, which is why the complete example further down includes one of each kind.
Quick Checklist: Run Through This Before Anything Else
- Open the console first. In most cases the browser already told you exactly what broke and on which line, before you even start guessing.
- Check the Network tab for the script file. A red 404 next to it means the file never loaded at all, usually because of a wrong path or a typo in the filename.
- Confirm the script runs after the page's elements exist. A script that references an element before it has been parsed fails immediately.
- Look for typos in function, variable, and event names. JavaScript is case sensitive, so onClick and onclick are not interchangeable, and neither are message and mesage.
- Hard refresh the page. A cached, outdated copy of a JavaScript file is a common reason changes seem to not apply at all.
If the console is completely clean and the page still behaves wrong, skip ahead to the complete example below. That's usually a silent logic bug rather than a crash.
How to Open the Console in Chrome DevTools
Everything else in this guide depends on being able to see what the browser actually thinks is happening, so this is worth doing first even if you feel confident about the code.
- Open DevTools. Right click anywhere on the page and choose Inspect, or press F12. On Windows and Linux, Ctrl+Shift+J opens Chrome DevTools directly on the Console tab. On Mac, use Cmd+Option+J instead.
- Select the Console tab along the top of the DevTools panel if it isn't already active.
- Reload the page. Any error the script threw during load appears here in red, along with the file name and line number where it happened.
- Click the blue link next to an error message to jump straight to that line in the Sources tab.
- Add your own console.log() statements at points in your code where you want to check a value, then look for that output in the same Console tab.
Firefox and Edge include the same kind of panel under a very similar name, so these steps translate directly even outside Chrome.
A Complete Example: Finding and Fixing Real JavaScript Bugs
Here's a small click counter, the kind of thing you'd genuinely build while learning DOM manipulation, with three real bugs mixed into it. Try to spot all three before reading the explanation below.
<head>
<script>
const incrementBtn = document.getElementById("incrementBtn");
const resetBtn = document.getElementById("resetBtn");
const countDisplay = document.getElementById("countDisplay");
const message = document.getElementById("message");
let count = 0;
incrementBtn.addEventListener("click", incrementCount);
resetBtn.addEventListener("click", resetCount);
function incrementCount() {
count = count + 1;
countDisplay.textContent = count;
if (count === 5) {
mesage.textContent = "Halfway to ten!";
}
}
function resetCount() {
const count = 0;
countDisplay.textContent = count;
}
</script>
</head>
<body>
<button id="incrementBtn">Add One</button>
<button id="resetBtn">Reset</button>
<p>Count: <span id="countDisplay">0</span></p>
<p id="message"></p>
</body>
Paste this into an online editor with a live console and nothing happens when you click either button, with no visible reaction at all until you check the console. Bugs like these often layer on top of each other too, so fixing the first one is usually what reveals the second. Here's what's actually going on, one bug at a time:
- Bug 1, the script runs too early. The script sits inside head, so it executes before the browser has parsed incrementBtn, resetBtn, or anything else in body. document.getElementById("incrementBtn") returns null, and calling addEventListener() on null throws a TypeError immediately, which stops the rest of the script cold. Neither button ever gets a click handler.
- Bug 2, a typo that only shows up sometimes. Inside incrementCount(), mesage is missing an s. Because that line only runs once count reaches 5, the page can look completely fine through four clicks and only throw a ReferenceError on the fifth, which makes it easy to miss during a quick test.
- Bug 3, a silent logic bug with no error at all. resetCount() declares its own local count with const, so it correctly resets the number shown on the page, but it never touches the actual count variable declared further up. The next click after a reset picks up right where the old count left off instead of starting over, and nothing in the console hints that anything is wrong.
Here's the same counter with all three fixed:
<body>
<button id="incrementBtn">Add One</button>
<button id="resetBtn">Reset</button>
<p>Count: <span id="countDisplay">0</span></p>
<p id="message"></p>
<script>
document.addEventListener("DOMContentLoaded", function () {
const incrementBtn = document.getElementById("incrementBtn");
const resetBtn = document.getElementById("resetBtn");
const countDisplay = document.getElementById("countDisplay");
const message = document.getElementById("message");
let count = 0;
incrementBtn.addEventListener("click", incrementCount);
resetBtn.addEventListener("click", resetCount);
function incrementCount() {
count = count + 1;
countDisplay.textContent = count;
if (count === 5) {
message.textContent = "Halfway to ten!";
}
}
function resetCount() {
count = 0;
countDisplay.textContent = count;
message.textContent = "";
}
});
</script>
</body>
Every fix here is small: wrapping the code in a DOMContentLoaded listener, adding one missing letter, and removing one keyword. That's typical of real JavaScript bugs, they rarely need a rewrite, only a specific line found and corrected. This site's own live editor lets you paste the broken version in, open its console, and watch the exact errors from bug one and two appear yourself before checking the corrected version above.
The Most Common Causes of "JavaScript Not Working"
Beyond the three bugs above, these account for most of the rest:
| Console Message | What It Usually Means | Typical Fix |
|---|---|---|
| Uncaught SyntaxError: Unexpected token | The code has invalid syntax, often a missing bracket, comma, or quote | Check the line number in the error and look for unclosed brackets or stray punctuation |
| Uncaught ReferenceError: x is not defined | Code refers to a variable or function that doesn't exist in that scope, often a typo | Check spelling and capitalization, and confirm the variable is declared before it's used |
| Uncaught TypeError: Cannot read properties of null | Code tries to use an element that getElementById couldn't find, usually because the script ran before that element existed | Move the script to the end of body, or wrap it in a DOMContentLoaded listener |
| Uncaught TypeError: x is not a function | Code tries to call something that isn't actually a function, often a misspelled method name | console.log(typeof x) to check what the value actually is |
| Nothing happens, no error at all | The logic runs but produces the wrong result silently, such as variable shadowing or a wrong comparison | Add console.log() at key points to see the actual values as the code runs |
| 404 for a .js file in the Network tab | The browser can't find the script file at the path given in the src attribute | Confirm the file path, name, and case match exactly |
One more distinction worth making: a button that responds when clicked, which you can confirm with a quick console.log() inside the handler, but looks visually wrong, is usually a CSS problem, not a JavaScript one. See what CSS actually does for how styling connects to markup in the first place.
How to Actually Test and Debug JavaScript
- Read the error message fully before doing anything else. The error type, the file name, and the line number are all handed to you directly, so most of the guessing other languages require simply isn't necessary here.
- Add console.log() at the start of a function first. If the log never appears, the function isn't being called at all, which is a completely different problem from a function that runs but returns the wrong value.
- Use breakpoints for anything timing related. The Sources tab in DevTools lets you pause execution on a specific line and inspect every variable at that exact moment, which is far more reliable than sprinkling console.log() everywhere for an async bug involving fetch() or a promise.
- Test small snippets before dropping them into a bigger project. An online JavaScript tester with a live preview, like the editor on this site, lets you confirm a function works in isolation in a few seconds instead of debugging it inside a much larger file. The guide on how to build and test a complete web page covers combining HTML, CSS, and JavaScript in one workflow like this.
Mistakes That Make Debugging Harder
- Assuming a quiet console means the code has no bugs. Logic bugs, like bug three in the example above, never throw anything.
- Changing several things at once. Undo everything except the one line you suspect, confirm the behavior, then change the next thing.
- Testing over the file:// protocol when the real project runs on a server. Certain features, especially fetch() and modules, behave differently or fail outright when opened directly as a local file instead of through an actual server.
- Ignoring the cache. A normal reload doesn't always grab a new copy of a JavaScript file. A hard refresh, or clearing the cache, is sometimes required to see your latest changes.
Expert Tips
- Name every function and variable something specific. handleSubmit tells you far more in a stack trace than doIt.
- Default to strict equality (===) instead of ==. It avoids an entire category of comparison bugs where two different types happen to look equal.
- Keep the console open by default while you develop. Catching an error the moment it happens is much faster than discovering it later from a bug report.
- Wrap DOM heavy scripts in a DOMContentLoaded listener as a habit, even for a small script, since it removes bug one from the example above as a possibility entirely.
Important Notes
A JavaScript error on your own page is not, on its own, a security problem. It's a sign that a specific line failed, nothing more.
The one situation worth real caution is pasting code you don't understand directly into the console, especially something a stranger asked you to run to unlock a feature or verify an account. Chrome and Firefox both warn about this specifically because it's a known method for stealing login sessions, and it has nothing to do with an ordinary debugging workflow.
FAQ
Why does nothing happen when I click a button?
In most cases, an earlier line in the same script already threw an error and stopped everything that came after it, including the code that would have attached the click handler. Open the console first, since it usually points straight at the actual line.
My console shows no errors, but the code still doesn't work. What now?
That's typically a silent logic bug rather than a crash, similar to bug three in the example above. Add console.log() at a few points in the function to see what values it's actually working with, since the code is running, just with the wrong result.
How do I open the console in Chrome?
Right click the page and choose Inspect, or press F12, then click the Console tab. Ctrl+Shift+J on Windows and Linux, or Cmd+Option+J on Mac, opens DevTools directly on that tab.
Why does my external JavaScript file not load at all?
Check the Network tab in DevTools for a 404 next to the file. That almost always means the path in the script tag's src attribute doesn't match the file's actual location or filename, including capitalization.
Does any of this apply to Node.js, or only JavaScript running in a browser?
This guide focuses on JavaScript running in a browser, alongside HTML and CSS. Node.js runs JavaScript outside the browser, without a DOM or a console tab, so it throws the same general categories of errors, but you read them in a terminal instead, and a few causes covered here, like a script running before an element exists, don't apply there at all.
What's actually different between a JavaScript error and an HTML problem?
HTML never stops rendering. A browser corrects invalid markup automatically and keeps going, as covered in why is my HTML not working. JavaScript is different: an uncaught error halts the rest of that script immediately, which is why one small JavaScript bug can look like several different features broke at once.
Can I test JavaScript online without setting up a project first?
Yes. A browser based live editor lets you paste a script in and see the console output and rendered result immediately, without installing anything, which is the fastest way to confirm whether a specific snippet works before adding it to a larger project.
Why did my code work yesterday and stop today, with nothing else changed?
A cached, outdated copy of the JavaScript file is the most common explanation. Try a hard refresh before assuming the code itself is broken.
Conclusion
"JavaScript not working" almost always breaks down into one of two very different problems: a script that hit an actual error and stopped, or one that ran to completion and simply produced the wrong result without saying so. The console tells you immediately which one you're dealing with, and the three bugs in the click counter example above cover the shape of nearly everything else you'll run into. Paste the broken version into this site's own live editor, open the console, and work through fixing all three yourself before checking the corrected code above. Finding a bug you fixed yourself sticks far better than reading about one.
Sources: MDN Web Docs: JavaScript error reference, MDN Web Docs: What went wrong, troubleshooting JavaScript.
NO Setups is a self-taught web development team focused on building practical tools and resources for developers. With hands-on experience in web development, open-source projects, and development workflows, the team creates simple solutions that help developers spend less time on setup and more time building.
Related Articles
Loading related articles…
