An unexpected-token SyntaxError marks where parsing could no longer continue; the defect may be an earlier delimiter, literal, operator, module-context mismatch, unsupported runtime syntax, or malformed generated source.
Diagnosis must inspect the deployed artifact and matching source map. Prevention combines parser-aware formatting, explicit runtime targets, structured data encoding, production builds, and smoke tests for every entry point and lazy chunk.
The error SyntaxError: Unexpected token occurs when JavaScript encounters code that doesn't follow the language syntax rules. This is a parse-time error, meaning the code won't even run.
// [wrong] Problem - Missing closing brace
function greet() {
console.log('Hello');
// SyntaxError: Unexpected end of input
// [ok] Solution - Add closing brace
function greet() {
console.log('Hello');
}
// [wrong] Problem - Missing comma
const user = {
name: 'John'
age: 30 // Missing comma
};
// [ok] Solution - Add comma
const user = {
name: 'John',
age: 30
};
// Missing closing brace
function calculate(a, b) {
return a + b;
// SyntaxError: Unexpected end of input
// Missing closing bracket
const numbers = [1, 2, 3, 4;
// SyntaxError: Unexpected token ';'
// Missing closing parenthesis
if (x > 10 {
console.log('Greater');
}
// SyntaxError: Unexpected token '{'
// Add closing brace
function calculate(a, b) {
return a + b;
} // [ok]
// Add closing bracket
const numbers = [1, 2, 3, 4]; // [ok]
// Add closing parenthesis
if (x > 10) { // [ok]
console.log('Greater');
}
// Use IDE with bracket matching
// Most editors highlight matching brackets
// Missing comma in object
const user = {
name: 'John'
age: 30 // SyntaxError: Unexpected identifier
};
// Missing comma in array
const colors = [
'red'
'blue' // SyntaxError: Unexpected string
'green'
];
// Add commas in object
const user = {
name: 'John', // [ok]
age: 30
};
// Add commas in array
const colors = [
'red', // [ok]
'blue', // [ok]
'green'
];
// Using reserved keyword as variable
const class = 'Math'; // SyntaxError: Unexpected token 'class'
const function = 'test'; // SyntaxError: Unexpected token 'function'
// Using await outside async function
function getData() {
const data = await fetch('/api'); // SyntaxError in non-async function
}
// Use different variable names
const className = 'Math'; // [ok]
const functionName = 'test'; // [ok]
// Use async function for await
async function getData() {
const data = await fetch('/api'); // [ok]
return data;
}
// Missing arrow
const add = (a, b) { return a + b; }; // SyntaxError
// Wrong arrow syntax
const multiply = (a, b) > a * b; // SyntaxError
// Missing parentheses for multiple parameters
const divide = a, b => a / b; // SyntaxError
// Add arrow =>
const add = (a, b) => { return a + b; }; // [ok]
// Or implicit return
const add = (a, b) => a + b; // [ok]
// Correct arrow syntax
const multiply = (a, b) => a * b; // [ok]
// Add parentheses for multiple parameters
const divide = (a, b) => a / b; // [ok]
// Single parameter doesn't need parentheses
const square = x => x * x; // [ok]
// Using regular quotes instead of backticks
const name = 'John';
const message = 'Hello ${name}'; // Doesn't interpolate
console.log(message); // "Hello ${name}"
// Missing closing backtick
const text = `Hello
World; // SyntaxError: Unexpected token
// Wrong interpolation syntax
const greeting = `Hello $name`; // Doesn't interpolate
// Use backticks for template literals
const name = 'John';
const message = `Hello ${name}`; // [ok]
console.log(message); // "Hello John"
// Close backtick properly
const text = `Hello
World`; // [ok]
// Use ${} for interpolation
const greeting = `Hello ${name}`; // [ok]
An unexpected-token SyntaxError means the parser could not continue under the grammar expected at that point. The highlighted token is where parsing became impossible, not always where the mistake began. Inspect the preceding delimiter, operator, literal, template expression, and statement boundary before deleting the reported token.
Syntax errors prevent the affected script or module from being evaluated. A surrounding runtime try/catch cannot catch source that failed to parse in the same compilation unit. Build tools, dynamic import rejection, worker startup, or explicit parsing APIs may expose the failure at another boundary.
Engine wording varies: an error may report an unexpected identifier, number, string, reserved word, end of input, or a more specific grammar rule. Preserve source URL, line, column, engine, and release, then map generated coordinates through matching source maps.
Start with the smallest failing file or expression. Auto-formatting can reveal unbalanced structure, but do not let a formatter rewrite generated or partially valid code before the original location is recorded. Compare the deployed artifact when local source parses successfully.
Unclosed parentheses, brackets, braces, strings, regular expressions, comments, and template literals often shift the reported location to a later line. Use editor bracket matching and inspect the last known valid construct. End-of-input errors almost always require looking backward for an unfinished construct.
Object literals, blocks, destructuring patterns, and arrow function bodies reuse similar punctuation with different grammar. Returning an object from a concise arrow requires parentheses around the object expression. A line break after `return`, `throw`, `break`, or `continue` can also change parsing or behavior through automatic semicolon insertion rules.
Mixing `??` directly with `&&` or `||` without parentheses is a syntax error by design. Optional chaining has invalid positions as well, including assignment targets and some tagged-template or constructor forms. Use explicit grouping that states the intended precedence rather than relying on visual order.
Regular-expression literals can be confused with division depending on grammar context, especially in generated source. Keep statements clear, use a parser-aware formatter, and avoid concatenating code strings. Data belongs in JSON or structured parameters rather than source text.
Import and export declarations belong at module top level, and `await` is allowed only in supported async contexts or module top level. A browser classic script cannot parse module syntax; use `type="module"`. Conversely, module loading changes scope, strictness, URL resolution, and top-level `this`, so the attribute is not merely a syntax switch.
A runtime that does not support emitted syntax may fail even though the source works in a newer development browser. Define browser and Node targets, transpile only what those targets require, and serve the correct modern or fallback bundle. Feature detection cannot run when the parser cannot parse the file.
File extension, package module type, import attributes, JSX, TypeScript, decorators, and other transformed syntax depend on the selected toolchain. Feed each file through the parser configured for its language. Shipping untransformed TypeScript types or JSX to a plain JavaScript engine produces immediate syntax failures.
MIME type and loading failures are separate from grammar errors but can appear near module startup. Check network responses, redirects, HTML error pages returned for script URLs, and content type before editing valid source. The response body may not be the JavaScript file expected.
Server-rendered values inserted into script source can break quoting, introduce closing tags, or create injection vulnerabilities. Serialize data with a context-appropriate structured encoder and read it as data. Do not escape JavaScript by applying an HTML escape function or by manually replacing a few quote characters.
JSON is a data format, not arbitrary JavaScript source. JSON.parse reports JSON grammar problems such as trailing commas, single-quoted strings, comments, or invalid escapes. Keep JSON parse failures distinct from source SyntaxErrors so the diagnostic identifies payload origin and byte position.
Template systems and code generators should produce source through an abstract syntax tree or a maintained generator when possible. Snapshot small generated examples, parse every generated artifact in tests, and include the generator version in diagnostics. One malformed input should not create a partially deployed bundle.
Content Security Policy may block eval-like code generation even when the string parses. Avoid `eval`, `new Function`, and string-based timers. They complicate source maps, security review, optimization, and error ownership while turning data defects into source-code defects.
Parse and lint every source file in continuous integration using the same module mode, language plugins, runtime targets, and build flags as production. A syntax check with the wrong parser can reject valid transformed syntax or accept source that the deployed runtime cannot execute.
Run a production build and smoke-load its entry points, lazy chunks, workers, service workers, and optional feature bundles. Dynamic chunks may escape tests that load only the initial page. Verify source maps belong to the same content-hashed files.
When bisecting a large generated failure, reduce by complete syntax units rather than deleting arbitrary lines that unbalance delimiters. Parser diagnostics, version control diff, and the first failing build are more reliable than guessing from the final token.
Add the exact source fragment, runtime target, or malformed generator input as a regression. Assert that valid neighboring cases still compile. The durable fix belongs in source or generation rules, not in a production error handler that can never run for an unparsed unit.
// A missing comma before `age` would make `age` look unexpected.
const user = {
name: "Mira",
age: 30
};
// Balanced delimiters prevent the parser from failing later.
const total = [4, 6, 8].reduce((sum, value) => {
return sum + value;
}, 0);
console.log(user.name, total);
function parseJsonResponse(raw) {
const trimmed = raw.trim();
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
throw new Error("Expected JSON but received: " + trimmed.slice(0, 30));
}
return JSON.parse(trimmed);
}
console.log(parseJsonResponse('{"status":"ok","count":2}'));
This error occurs when JavaScript encounters code that doesn't follow syntax rules. Common causes include missing brackets/braces, missing commas, using reserved keywords incorrectly, or invalid arrow function syntax.
Read the error message to find the exact location, check for missing brackets or commas, ensure proper syntax for arrow functions and template literals, and use an IDE with syntax highlighting.
This usually means there's a missing closing parenthesis before the brace, or incorrect syntax in the previous line. Check if statements, function calls, and arrow functions for proper syntax.
Explore 500+ free tutorials across 20+ languages and frameworks.