This error occurs when the JavaScript parser encounters a token it does not recognize at the given position. It typically indicates missing brackets, quotes, semicolons, invalid characters, or syntax violations that prevent the code from being parsed correctly.
The "Unexpected token" syntax error indicates that the JavaScript parser found a piece of code that violates the language's syntax rules. The parser reads your code token by token and expects specific patterns based on JavaScript grammar. When it encounters something unexpected, it cannot continue parsing and throws this error. The specific location and token vary depending on what went wrong. Common culprits include: - Missing or mismatched brackets, parentheses, or braces - Unclosed string literals - Invalid operator placement - Reserved keywords used as variable names - Invisible characters from copying code - Type annotations without proper transpilation The error message often includes the approximate line number where the parser stopped, though the actual problem may be on the preceding lines.
The error message includes a line number where the parser failed. Check that line and the few lines before it.
The actual problem is often 1-5 lines before the reported error line. The parser only realizes there's a problem when it encounters the unexpected token.
Common examples:
Missing closing brace (error reported on line 5, problem on line 2):
function getData() {
const data = fetchData();
// Missing closing brace here
console.log(data); // <- Error reported hereUnclosed string (error reported on line 3):
const message = "Hello World; // <- Missing closing quote
const name = "John
console.log(message); // <- Error reported hereExtra bracket:
const arr = [1, 2, 3];] // <- Extra bracket here
console.log(arr); // <- Error reported hereLinters like ESLint can pinpoint syntax errors more clearly than runtime errors.
Install ESLint:
npm install --save-dev eslint
npx eslint init # Follow the prompts to set upRun ESLint on your file:
npx eslint your-file.jsESLint output is typically more detailed:
file.js
1:34 error Parsing error: Unexpected token )
1 | function getData(a, b,) {
| ^This clearly shows there's an extra comma before the closing parenthesis.
In VS Code:
- Install the ESLint extension
- Problems will show directly in the editor with red squiggles
- Hover over the error for more details
Balance all brackets, parentheses, and braces.
Before (incorrect):
function getData() {
const data = [1, 2, 3; // <- Wrong bracket type
return data
// Missing closing braceAfter (correct):
function getData() {
const data = [1, 2, 3]; // <- Correct bracket type
return data;
}Use an editor with bracket matching:
- Place cursor on an opening bracket and it highlights the closing one
- Most editors (VS Code, WebStorm, Sublime) support this
- Use keyboard shortcuts to jump between matching brackets
Common bracket pairs:
- ( ... ) - Function calls, grouping
- [ ... ] - Arrays, indexed access
- { ... } - Objects, blocks, statements
Ensure all string literals have matching quotes.
Before (incorrect):
const name = "John;
const city = 'New York;
const message = `Hello`; // backticks don't match quotes aboveAfter (correct):
const name = "John";
const city = 'New York';
const message = `Hello`;Important: Match quote types:
"string with double quotes" // Correct
'string with single quotes' // Correct
`string with backticks` // Correct
"mismatched quote' // WRONGCheck for smart quotes:
If you copied code from a website, Word document, or PDF, it may contain "smart quotes" instead of regular quotes.
Wrong (from Word/PDF):
const message = "Hello"; // These are fancy curly quotesRight (plain text):
const message = "Hello"; // These are straight quotesFix: Delete the string and retype it manually in your editor, or paste into a plain text editor first.
Remove invisible or invalid characters, especially from pasted code.
Check for invisible characters:
# Show all whitespace characters (including invisible ones)
cat -A your-file.js | head -20
# Look for unusual characters like zero-width spaces, special unicode
hexdump -C your-file.js | head -20Common culprits when pasting:
- Smart quotes from Word: curly quotes (replace with regular straight quotes)
- Zero-width spaces (from some web interfaces)
- Em dashes and en dashes (replace with -)
- Tab characters mixed with spaces
Solutions:
1. Delete the problematic line and retype manually
2. Paste into a plain text editor first (Notepad, plain text mode)
3. Use your editor's find-and-replace to swap smart quotes with regular quotes
Using sed to clean common issues:
# Replace smart quotes with regular quotes
sed -i 's/[""]/"/g; s/['']/'"'"'/g' your-file.jsDo not use JavaScript reserved words as variable or function names.
Reserved words you cannot use:
// Cannot use as names:
const if = 5; // WRONG
const class = {}; // WRONG
function for() {} // WRONG
let while = true; // WRONGLegal alternatives:
// Correct versions:
const ifCondition = 5;
const myClass = {};
function loop() {}
let whileActive = true;Complete list of reserved words:
Abstract, arguments, await, boolean, break, byte, case, catch, char, class, const, continue, debugger, default, delete, do, double, else, enum, eval, export, extends, false, final, finally, float, for, function, goto, if, implements, import, in, instanceof, int, interface, let, long, native, new, null, package, private, protected, public, return, short, static, super, switch, synchronized, this, throw, throws, transient, true, try, typeof, var, void, volatile, while, with, yield
Context matters: Some reserved words can be used in specific contexts (like as object properties):
const obj = {
class: 'main', // OK as object property
for: function() {}, // OK as object property
};
console.log(obj.class);If parsing JSON, ensure the data is actually valid JSON, not HTML or malformed data.
Common issue - server returns HTML instead of JSON:
// If your server returns an error page as HTML
const response = await fetch('/api/data');
const json = await response.json(); // <- Error if response is HTMLFix - check content type first:
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
if (!response.headers.get('content-type')?.includes('application/json')) {
throw new Error('Response is not JSON');
}
const json = await response.json();Validate JSON structure:
// Valid JSON
{
"name": "John",
"age": 30,
"items": [1, 2, 3]
}
// INVALID JSON - trailing comma
{
"name": "John",
"age": 30, // <- Extra comma not allowed
}
// INVALID JSON - single quotes
{
'name': 'John' // <- Single quotes not valid in JSON
}
// INVALID JSON - unquoted keys
{
name: "John" // <- Keys must be quoted in JSON
}Test JSON validity:
# Use jq to validate JSON
echo '{"name":"John"}' | jq .
# Pretty-print and validate
curl https://api.example.com/data | jq .Parser Recovery:
Modern JavaScript engines try to recover from syntax errors gracefully, but the process varies. Node.js stops parsing immediately upon encountering an unexpected token and will not execute any code in that file. Some bundlers and transpilers may attempt recovery or partial parsing.
Transpilation Requirements:
If using TypeScript, JSX, or stage-proposal syntax, ensure your build tool is configured correctly:
- TypeScript: Run tsc or tsx instead of node directly
- JSX: Use @babel/preset-react or @swc/preset-react
- Modern syntax: Configure your transpiler target appropriately
Error Position Accuracy:
The line number reported is where the parser failed, not necessarily where the problem is. For complex expressions or nested structures, the error can appear several lines after the actual issue. Use binary search: comment out half your code, run it, and narrow down the problem.
Debugging Strategy:
1. Copy the exact error message and search for it
2. Check the file immediately before the reported line
3. Use a linter (ESLint, TypeScript) for faster feedback
4. Test incrementally - write code in small chunks
5. Use an IDE with real-time syntax checking
6. Never ignore squiggly red lines in your editor
Common Patterns:
- Copy-paste errors: Always verify code copied from websites
- Merge conflicts: After git merge, check for conflict markers
- File encoding: Ensure files are UTF-8 without BOM
- Mixed line endings: Use LF consistently, not CRLF
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams