Your code looks fine. The parser disagrees, nothing runs, and you are left asking what a parse error actually is: a failure to build valid structure from source input.

Same failure, different wording every time. PHP, JavaScript, JSON, XML, Python, or an APK stuck on an Android phone.

This guide covers:

  • How a parser produces the message in the first place
  • Why the reported line number usually lies
  • Causes and fixes for each language and file format
  • Tools that catch the fault before anything ships

By the end, an unexpected token message stops being cryptic. You will know exactly where to look first, and why the flagged line is rarely the guilty one.

What Is a Parse Error

A parse error is a failure that happens when a parser cannot build a valid structure from the input it receives. The input breaks the grammar rules of the language or file format.

Nothing runs. The parser gives up before a single line executes, which is exactly what separates a parse error from a bug.

Parsing sits in the middle of the compilation pipeline. Source text moves through lexical analysis, then syntax analysis, then semantic analysis, and a parse error fires during that second stage.

The same failure carries 4 different names depending on which tool reports it: syntax error, parsing error, unexpected token, and SyntaxError.

Input TypeParser / ProcessorTypical Error Message
Source CodeCompiler or InterpreterParse error: syntax error, unexpected ...
Data Formats (JSON, XML, YAML)Format ParserUnexpected token / Not well-formed
Package Files (APK)Android Package ManagerThere was a problem parsing the package

Altadmri and Brown logged 37 million compilation events from over 250,000 students in the University of Kent Blackbox dataset. Unbalanced parentheses, brackets, and quotation marks topped their frequency list, and every one of those is a parse failure.

Have you seen the latest WordPress statistics?

Discover the latest WordPress statistics: market share, security trends, performance data, and revenue insights that shape the web.

Check Them Out →

So this is not an exotic category. It is the single most common thing that stops code from running.

How a Parser Produces an Error

A parser produces an error when the token stream stops matching any rule in the grammar. The tokenizer splits input into tokens first, the parser checks their order second, and the failure gets reported at the position where the mismatch became undeniable.

Abstract syntax tree construction is the actual job. The parser tries to attach each token to a node, and when no rule accepts the next token, tree building halts.

Two parser designs dominate real language implementations:

  • Recursive descent: one function per grammar rule, used by PHP-adjacent hand-written parsers and by CPython’s PEG parser since 3.9
  • LR and LALR: table-driven, used by older Bison-generated compilers, and the source of the famously blunt “syntax error” message

Most parsers then attempt panic-mode recovery, skipping tokens until they find something that looks like a fresh statement. That recovery is why one missing brace can produce 12 unrelated errors below it.

The cost of getting this wrong is not trivial. ACM Queue reports developers spend 35 to 50 percent of their time validating and debugging, with testing and verification eating 50 to 75 percent of total project budgets.

What “Unexpected Token” Actually Means

Plain translation: the parser reached a symbol that no grammar rule permits at that exact position.

The token named in the message is almost never the guilty one. It is the first legal-looking thing the parser met after the real mistake.

A missing comma inside an object gets reported as an unexpected string. A missing closing quote gets reported as an unexpected keyword three lines down.

Why the Reported Line Number Is Often Wrong

Parsers report detection points, not fault points. An opening brace on line 40 that never closes stays valid until the file ends, so the error lands on line 312.

CPython addressed this directly. Since Python 3.10, unclosed brackets report '{' was never closed and point back to the opening character instead of dumping an EOF message at the bottom of the file (python.org).

PHP and older JavaScript engines still report detection points. Read upward from the flagged line, not downward.

Parse Error vs Runtime Error vs Logic Error

Parse errors are caught before execution, runtime errors during execution, and logic errors never at all. A parse error produces zero output. A runtime error produces partial output plus a stack trace. A logic error produces complete, wrong output with no message.

Error ClassDetected AtOutput ProducedExample
Parse ErrorParse timeNoneMissing semicolon, unclosed brace
Semantic (Compile-Time)After parsing, before executionNoneUndeclared variable, type mismatch
Runtime ErrorDuring executionPartialNull reference, division by zero
Logic ErrorNever automaticallyComplete but incorrectInverted comparison operator

In one analysis of failed novice submissions, syntax errors accounted for 52.4 percent of all errors and semantic errors the remaining 47.6 percent.

Fix time splits the classes more sharply than frequency does. A 2025 arXiv systematic review describes syntax errors as ubiquitous but quick to fix, while semantic and logical faults stay expensive.

Undo’s research puts the average at 13 hours to fix a single software failure, with 41 percent of engineers naming reproduction as their biggest barrier. Parse errors skip that barrier entirely, since they reproduce on every single run.

Server-side, the distinction shows up in message wording. A PHP parse error stops the file at compile time, while a WordPress fatal error usually means valid syntax that blew up mid-execution.

What Causes Parse Errors

Unbalanced delimiters cause more parse errors than every other trigger combined. A 2025 arXiv review of beginner mistakes names mismatched parentheses, curly braces, and square brackets the single most significant syntax fault.

The rest of the list, ordered roughly by how often it lands in a bug tracker:

  • Missing semicolons and statement terminators
  • Unterminated string literals and broken escape sequences
  • Mixed tabs and spaces in indentation-sensitive grammars
  • Reserved keywords used as identifiers
  • Stray characters left behind by a bad paste

Brown and Altadmri also found educators formed only a weak consensus on which mistakes are most frequent, and their rankings matched student data only moderately. Which is worth remembering before anyone insists they know what broke the file.

Anyone working through a specific message will get further with a message-by-message approach to tracking down syntax faults than with a general checklist.

Invisible Characters and Encoding Faults

Some parse errors have no visible cause at all. The file looks correct and still refuses to compile.

The usual suspects:

  • BOM markers: a UTF-8 byte order mark before an opening PHP tag pushes 3 invisible bytes into output
  • Non-breaking spaces: U+00A0 renders identically to a space and parses as garbage
  • ANSI to UTF-8 mismatches: accented characters in comments turn into invalid byte sequences

Re-saving as UTF-8 without BOM fixes most of these in one step.

Copy-Paste Errors From Web Sources

Nothing wastes an afternoon faster than code copied out of a blog post that ran the snippet through a rich text editor.

Smart quotes are the main offender. Typographic quote marks look almost identical to straight quotes at 14px, and no parser accepts them.

Em dashes substituted for double hyphens and ellipsis characters replacing three periods do the same thing.

Parse Errors in PHP

PHP reports parse errors in one fixed format: Parse error: syntax error, unexpected [token] in /path/file.php on line N. The script never executes, which on a public site means a blank page rather than a broken one, because output halts before the theme renders anything.

PHP still runs 71.8 percent of websites with a detectable server-side language, and WordPress accounts for roughly 42.6 percent of all websites (W3Techs, 2026). The exposure here is enormous.

Common triggers:

  • Missing semicolon on the line above the reported one
  • Unclosed brace in a function or conditional block
  • Unexpected end of file, which means a block was opened and never closed
  • Short open tags after PHP 8.0 removed them

PHP 5 and PHP 7 messages used T token constants such as TSTRING, TVARIABLE, and TENDIF. PHP 8 rewrote these into readable form, so the older unexpected-token wording now appears mostly on legacy hosts.

PHP 8 also removed curly brace array access, so $array{0} is a hard parse error on every modern host. By 2026 PHP 8 had clearly overtaken PHP 7 on the public web, and WordPress now recommends 8.3 or greater.

Run php -l yourfile.php before uploading anything. The linter parses without executing and reports the same message the server would.

The single highest-risk file on a WordPress install is the theme functions file. A stray brace while making changes to functions.php locks the admin panel along with the front end, producing the blank white screen that gives no clue what happened.

Parse Errors in JavaScript and JSON

Browsers throw SyntaxError at parse time, before any statement in the file runs. JSON parse failures behave the same way but come from data rather than code, and the two get confused constantly because both surface as unexpected token messages in the console.

JetBrains found 61 percent of developers use JavaScript regularly, making its parse errors the most widely encountered of any language.

Engine wording differs, and the difference matters when searching for a fix:

FaultChrome DevTools (V8)Firefox (SpiderMonkey)
Stray BraceUnexpected token '}'expected expression, got '}'
Unclosed StringInvalid or unexpected tokenunterminated string literal
Bad JSONUnexpected token in JSON at position NJSON.parse: unexpected character

What breaks JSON.parse: trailing commas, single quotes, unquoted keys, and the literals NaN and Infinity. All 4 are legal JavaScript and illegal JSON.

Automatic semicolon insertion causes the opposite problem. ASI silently repairs some missing semicolons and then breaks on a return statement followed by a newline, which parses as a bare return.

Module and script contexts parse differently too. An import statement in a file loaded without type="module" is a parse error, not a resolution failure.

Before hunting through a payload by eye, run it through a JSON formatter or node --check. Indentation exposes an unclosed bracket in about two seconds.

Why “Unexpected Token <” Is Almost Never a JSON Problem

Position 0 means the very first character was wrong. A left angle bracket at position 0 is the opening of an HTML document.

The server returned a page instead of data. Usually a 404, a login redirect, or a 500 server error page that the fetch code passed straight into JSON.parse without checking the status.

Check the response status and content type before parsing. The JSON is fine, the API endpoint is what failed.

Parse Errors in Python

Python raises 3 distinct parse-time exceptions: SyntaxError for grammar violations, IndentationError for inconsistent block depth, and TabError for mixed tabs and spaces. All 3 stop the interpreter before the first statement executes.

A study of Python compiler error messages recorded 115 errors across its participants, with SyntaxError the most common type by a clear margin, followed by NameError.

Python 3.10, released October 2021, rewrote most of this reporting. Pablo Galindo’s work on the CPython parser replaced the old generic messages with specific ones:

  • '(' was never closed instead of unexpected EOF while parsing
  • expected ':' for a missing colon after a block header
  • invalid syntax. Perhaps you forgot a comma? with the offending range highlighted

Unclosed string literals now point to where the string started rather than reporting EOL at the end of the file.

The classic Python 2 holdover still trips people up. print "hello" raises a SyntaxError in every Python 3 interpreter, because print stopped being a statement.

Check a file without running it using python -m pycompile script.py. It compiles to bytecode and reports parse errors without executing a single line, which matters when the script writes to a database.

Parse Errors in HTML, XML, and Configuration Files

Markup and configuration parsers split into 2 camps. XML and YAML fail hard and refuse to produce a document, while HTML5 parsers recover from almost anything.

That difference explains why a broken page still renders and a broken workflow file kills the whole pipeline.

FormatStrictnessBehavior on Malformed Input
HTML5PermissiveSilently repaired; page still renders
XMLStrictDocument rejected; nothing displays
YAMLStrictParse failure; job never starts
.htaccessStrict500 response across the whole site

The HTTP Archive Web Almanac scanned nearly 17 million websites for its 2024 edition. 93 percent of mobile pages carry the standard doctype, and the 2.2 percent with no doctype at all still render, just in quirks mode.

The same report found 29 obsolete elements in the HTML specification, and every one except keygen still appears somewhere in the dataset. No parse error, no warning, nothing.

XML gives no such mercy. Firefox reports “XML Parsing Error: not well-formed” and stops rendering entirely.

The 3 usual causes are unescaped ampersands, unclosed tags, and wrong nesting order. An RSS feed with a raw & in a title breaks in every feed reader at once.

YAML fails on whitespace. A tab character anywhere in a Docker Compose file or a GitHub Actions workflow produces a parse failure before a single step runs.

GitHub reports this as a startup failure rather than a job failure, which is a useful signal. The workflow definition never parsed, so nothing was scheduled.

Run xmllint --noout file.xml for markup, yamllint for config, and the W3C Markup Validation Service for pages. For server config, nginx -t catches a bad directive before a reload takes the site down.

What “There Was a Problem Parsing the Package” Means on Android

The Android package manager could not read the APK manifest. This is a parse failure at the file level rather than the code level, and the installer stops before extracting anything.

Redownloading fixes the majority of cases, because a truncated transfer leaves the manifest incomplete.

CauseFix
Partial or Corrupted DownloadRedownload the file and compare its file size/checksum if available
minSdkVersion Above Device OSFind a build that supports the device’s older API level
Unsigned or Badly Signed PackageObtain the APK from the original developer or a trusted official source
Unknown Sources DisabledGrant the required install permission to the app/source attempting the installation

Version mismatch is the second most common trigger. Google Play now requires new apps and updates to target Android 16 (API level 36) or higher, and existing apps to target API 35 to stay visible to new users on newer devices.

An APK built against a target the device cannot satisfy gets rejected at the manifest stage.

Renaming an APK is harmless. Repacking one is not, since altering the archive structure invalidates the signature block and the parser rejects the file.

Running the install through adb gives a real error code instead of the generic dialog. INSTALLPARSEFAILEDNOCERTIFICATES tells you the signing failed, which the on-device message never distinguishes from a bad download.

Google’s own analysis found over 50 times more malware from internet-sideloaded sources than from Play Store apps. Developer verification for sideloaded installs opened in early access in October 2025 and reaches the first markets, including Brazil and Indonesia, in September 2026.

How to Fix a Parse Error

Start at the reported line, then read upward. The fault sits earlier in the file about as often as it sits on the flagged line, because parsers report where they noticed rather than where the mistake happened.

The sequence that works in any language:

  • Check the last block you edited before anything else
  • Read 20 lines upward from the reported line number
  • Use the editor’s bracket matching to find the unclosed pair
  • Re-save the file as UTF-8 without BOM
  • Roll back to the last working version and reapply changes in small pieces

Coralogix research puts debugging at 75 percent of developer time, roughly 1,500 hours a year. Parse errors are the cheapest slice of that number to reclaim, since they reproduce on every run.

Turning on error display helps on servers that swallow output. Enabling PHP error output on a WordPress install replaces a blank page with the actual file path and line number.

The Binary Search Method for Isolating the Break

Comment out half the file. If the error disappears, the fault is in the commented half. If it stays, it is in the other half.

Repeat on the failing half. A 2,000 line file gets narrowed to a single statement in about 11 rounds.

Git offers the same logic across commits. git bisect walks the history and identifies which commit introduced the break.

When the Error Is in an Included File, Not the One Reported

Include statements move the problem. An unclosed brace in a partial gets reported against the parent file, because that is where the parser was reading when the token stream ran out.

Watch for these two signals:

  • The reported line contains an include, require, or import statement
  • The error says unexpected end of file on a file that clearly ends correctly

A missing path produces a different class of message entirely. The failed to open stream warning means the file was not found, not that its contents were malformed.

Tools That Catch Parse Errors Before They Ship

Every major language ships a native syntax checker that parses without executing. These take under a second, run offline, and report the exact message the production server would give you.

Language or FormatValidation Command
PHPphp -l file.php
JavaScriptnode --check file.js
Pythonpython -m py_compile file.py
XMLxmllint --noout file.xml

Linters go further by catching style and logic problems alongside grammar: ESLint, PHPCodeSniffer, Pylint, and Flake8 are the standard four.

ESLint v9.0.0 landed in April 2024 with flat config as the default, and the team shipped official language plugins for Markdown and JSON by year end. Rust-based alternatives arrived shortly after, with Biome 2.x and Oxlint 1.0 both released in June 2025.

Editor-level parsing catches most of this before a file is ever saved. Stack Overflow’s 2025 survey of 49,000 developers put VS Code at 75.9 percent usage, up from 73.6 percent in 2024, and its bracket pair colorization makes an unclosed brace visible at a glance.

Formatting is a diagnostic in itself. Running markup through an HTML formatter exposes a missing closing tag through the indentation, before any validator gets involved.

For payloads and config, JSONLint, YAML Lint, and the W3C Markup Validation Service handle what command line tools miss.

Then push the check upstream. Undo’s research found 88 percent of organizations have adopted continuous integration, and a lint stage in that pipeline blocks a parse error from ever reaching a server.

On a live site, the server error log is where the real message ends up when the browser shows nothing at all.

How to Prevent Parse Errors

Prevention is mostly editor configuration and deployment discipline. Consistent indentation, auto-closing brackets, version control, and a rule against editing production files remove the conditions that create parse errors in the first place.

Coralogix estimates $113 billion spent annually in the US alone on identifying and fixing product defects. The habits below cost nothing.

Editor setup:

  • EditorConfig to enforce one indentation policy across the team
  • Prettier for automatic formatting on save
  • Auto-closing brackets and quote pairs switched on
  • One file encoding, UTF-8 without BOM, standardized everywhere

Type code manually instead of pasting from formatted web pages. Smart quotes and non-breaking spaces enter a codebase almost exclusively through the clipboard.

Keep commits small enough to roll back cleanly. A commit touching 3 files gets reverted in seconds, while a commit touching 40 becomes its own debugging session.

Never edit production files through FTP or a hosting file manager. There is no undo, no syntax check, and no version history when the save button breaks the site.

Core files deserve the same rule. Deciding whether core files should be edited at all is worth settling before a deadline forces the answer.

On a CMS, use a staging copy and a child theme. Most reports of a syntax error taking down a WordPress site trace back to a live edit that nobody linted first.

FAQ on What Is A Parse Error

What is a parse error in simple terms?

A parser read your file, hit something the grammar does not allow, and stopped. Nothing executes. The file is rejected before a single instruction runs, which is why you see no partial output at all.

What causes a parse error?

Unbalanced brackets top every study of the subject. After that: missing semicolons, unterminated strings, mixed tabs and spaces, reserved keywords used as variable names, and invisible characters pasted in from a formatted web page.

Is a parse error the same as a syntax error?

Yes, in practice. Different tools pick different labels for the identical failure, and PHP says parse error while Python and JavaScript raise SyntaxError. The underlying cause and the fix are the same.

Why does the reported line number look wrong?

Parsers report where they noticed the problem, not where you made it. An unclosed brace stays valid until the file ends, so the error surfaces hundreds of lines below the actual mistake.

What does “unexpected token” actually mean?

The parser found a symbol that no grammar rule permits at that position. The named token is almost never the culprit. It is the first legal-looking thing encountered after the real fault.

How do I fix a parse error fast?

Read upward from the flagged line, check the block you edited last, and use bracket matching. Failing that, comment out half the file and repeat until the break is isolated.

What causes “There was a problem parsing the package” on Android?

The package manager could not read the APK manifest. Usually a partial download, sometimes a minSdkVersion higher than the device supports, a broken signature, or install permission never granted to the source app.

Why does JSON.parse throw an unexpected token error?

Trailing commas, single quotes, and unquoted keys are all legal JavaScript and illegal JSON. An unexpected left angle bracket at position 0 means the server returned an HTML page instead of data.

Can a parse error take down an entire website?

On PHP sites, yes. One stray brace in a theme or plugin file halts output before anything renders, producing a blank page across the front end and the admin panel together.

How do I check for a parse error without running the code?

Every major language ships a linter that parses without executing: php -l, node --check, python -m pycompile, and xmllint --noout. Each returns the same message your server would.

Conclusion

A parse error is a grammar failure, not a bug. The tokenizer split your input, the parser found no rule that accepted the next token, and abstract syntax tree construction stopped right there.

Which makes the fix mechanical rather than clever.

Read upward from the flagged line. Check the file encoding. Run the native syntax checker before anything touches a server.

The habits that prevent this whole class of failure are boring and cheap: consistent indentation enforced by EditorConfig, auto-closing brackets, small commits, and a lint stage in the pipeline.

Set those up once and the category mostly stops appearing.

Next time an editor flags an unclosed delimiter, you already know exactly what the parser is complaining about.