syntax error, unexpected: how to fix a PHP parse error in WordPress

A single missing bracket or semicolon in a PHP file can take your entire WordPress site down. The error message tells you exactly where it is, and the fix is usually two edits away.

Your site shows a message that starts with Parse error: syntax error, unexpected, followed by a file path and a line number. Or it shows nothing at all: a white page, or the generic "There has been a critical error on this website" screen with the real parse error hidden behind it. Either way, PHP found something in your code it could not understand and stopped the whole site from loading.

What this error actually means

A parse error is PHP refusing to run a file because the syntax is wrong. According to the PHP manual's error constants, E_PARSE is a compile-time error: it happens before your script runs at all. One misplaced character and the entire file is unusable, which in WordPress usually means the entire site is unusable, because that file is loaded on every request.

A complete WordPress parse error looks like this:

Parse error: syntax error, unexpected token "function" in /home/yoursite/public_html/wp-content/themes/yourtheme/functions.php on line 42

Three pieces of information matter, in this order:

  1. The file. Here: wp-content/themes/yourtheme/functions.php. This tells you whether the problem is in a theme, a plugin, wp-config.php, or something else.
  2. The line number. Here: 42. This is almost always within a few lines of the actual mistake. PHP reports the line where it first noticed something was wrong, which can be one or two lines past the real cause (for example, a missing semicolon on line 41 reported as an unexpected token on line 42).
  3. The unexpected token. Here: "function". PHP tells you what it found that it did not expect. An unexpected ) usually means an opening ( is missing earlier. An unexpected } usually means an extra closing brace or a missing opening one. An unexpected function often means the previous statement was not terminated with ;.

If you cannot see the error at all, skip down to Diagnose before you touch anything and turn on WP_DEBUG first. Everything else in this article depends on knowing the file and line number.

Common causes, ordered by likelihood

  1. You edited a theme's functions.php from the WordPress admin editor. This is the single most common way to brick a WordPress site. You add a snippet, hit save, and the admin immediately locks you out because WordPress tries to load the same broken functions.php to render the dashboard. You end up with no front end, no back end, and no obvious way back.
  2. You pasted a code snippet from a blog post or forum. A snippet written for PHP 5.6 or for a different WordPress version can contain syntax that PHP 8.2 no longer accepts. "Curly brace" access like $string{0} was removed in PHP 8.0, and old tutorials still use it. Snippets without surrounding <?php ?> tags, or with <?php accidentally pasted twice, also trip the parser immediately.
  3. A plugin or theme update shipped broken PHP for your PHP version. The developer tested on PHP 8.3, you are on PHP 8.2, and a language construct they relied on behaves differently. Rare but real. You will see the error immediately after the update completes. If the update never completed, you may also see a stuck "Briefly unavailable for scheduled maintenance" page.
  4. A missing or extra bracket, brace, semicolon, or quote. The classic. One character. You added a new function to functions.php, forgot the closing }, and PHP reports "unexpected end of file" at the very last line. Or you opened a string with " and closed it with ', and PHP happily ate half the file looking for the matching quote.
  5. An incomplete FTP upload. The upload was interrupted, the file is truncated, and PHP hits the end of a function or class that was never closed. Re-uploading from a clean copy fixes it.

The common thread: almost every parse error appears immediately after a code change you or something else just made. "It was working this morning, now it is broken" is the story in 95 percent of cases. That is good news, because it means you know roughly where to look.

Diagnose before you touch anything

Before you edit any file, confirm you can actually see the error and know which file is broken.

  • If you see the full Parse error: message in the browser, write down the file path and line number. Skip to the fix.
  • If you see "There has been a critical error on this website", WordPress is hiding the error on purpose because WP_DEBUG is off. This is the default on live sites. You need to turn it on temporarily. Work through my critical error on this website guide first: WordPress 5.2 and later send a recovery mode email to the site admin address that names the faulty plugin or theme directly. That email alone is often enough to skip the rest of this article.
  • If you see a blank white page with nothing on it, you have hit the classic White Screen of Death. Same fix: turn on WP_DEBUG to reveal the underlying parse error.

To enable debug output, connect to your site over SFTP or open the file manager in your hosting panel. Open wp-config.php in the WordPress root (the folder with wp-content in it) and find this line:

define( 'WP_DEBUG', false );

Change it to:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

WP_DEBUG_LOG writes errors to wp-content/debug.log instead of showing them to visitors. WP_DEBUG_DISPLAY set to false keeps the error off the public site. Reload the page, then open wp-content/debug.log. You should see the full parse error with file and line. Write it down.

You will know diagnosis is complete when you have the exact file path and the exact line number. If the log is empty, your host may be suppressing PHP errors at the server level. In that case check the hosting control panel's PHP error log (cPanel calls it Errors, DirectAdmin calls it Site Error Log, Plesk calls it Logs). The same entry will be there.

Turn debug off again when you are done: set WP_DEBUG back to false. Leaving it on leaks paths and error details to visitors.

The fix: revert or repair the broken file

You now know which file broke and roughly where. You have three options, in order of safety. Pick the first one that applies to your situation.

Option 1: Use the WordPress 5.2+ recovery email to deactivate the offender

If the broken file belongs to a plugin or a theme, and you run WordPress 5.2 or later (which is almost certainly the case on a modern install, current as of WordPress 6.7), WordPress already sent you an email. It goes to the site admin address in Settings → General and has a subject line like "Your Site is Experiencing a Technical Issue". The recovery mode feature was introduced in WordPress 5.2 for exactly this situation.

  1. Check the admin email inbox, including spam. The sender is your own site.
  2. Open the email. It names the plugin or theme that crashed.
  3. Click the recovery mode link in the email. You are logged into a working copy of wp-admin with the offending extension paused.
  4. Go to Plugins (or Appearance → Themes). Deactivate, delete, or revert the named extension. If you installed an update recently, the previous version is still available in the WordPress plugin directory for most plugins, or in your host's file backups.
  5. Log out of recovery mode. Reload the public site.

You will know it worked when the site loads normally for visitors and the error is no longer in debug.log.

If no email arrived, your site's outgoing mail is broken, or the problem is not in a plugin or theme (it is in wp-config.php, .htaccess, or a core file), skip to Option 2.

Option 2: Revert the broken file over SFTP or the file manager

This is the safest manual fix. You are not editing the file, you are replacing it with a known-good version.

  1. Open your SFTP client (FileZilla, Cyberduck, Transmit) or your host's file manager. Connect to the server.
  2. Navigate to the broken file from the parse error. For a theme: wp-content/themes/yourtheme/functions.php. For a plugin: wp-content/plugins/pluginname/pluginname.php or whichever file the error named.
  3. If the broken file is a plugin or theme file: download a fresh copy of the same version from wordpress.org/plugins or the developer's site. Upload it, overwriting the broken one. If you were on a newer version that the directory no longer hosts, revert to the previous version from your host's daily backup instead.
  4. If the broken file is functions.php in an active theme and you edited it yourself: rename the broken functions.php to functions.php.broken so you still have your changes to read, then upload a clean functions.php from the theme's original ZIP download. The site should come back immediately, because WordPress simply loses your custom code until you re-add it carefully.
  5. If the broken file is wp-config.php or .htaccess: both files have clean sample versions to compare against. For wp-config.php, WordPress ships a wp-config-sample.php next to it you can use as a reference. For .htaccess, the WordPress.org default rewrite rules will regenerate a working file when you save permalinks in Settings → Permalinks.
  6. Reload the site.

You will know it worked when the front page loads normally, debug.log has no new Parse error entries, and wp-admin is reachable.

Option 3: Fix the line directly (only if you know what you broke)

If you are the one who just added a code snippet and you know exactly which lines, you can open the file in a proper editor and fix the specific mistake. Do not edit PHP in a plain text editor like Notepad. Use VS Code or any editor with PHP syntax highlighting and bracket matching: the editor will underline the broken line before you even save the file.

Common fixes that match common error messages:

Error text Likely cause Fix
unexpected token "function" or unexpected identifier Missing ; on the previous line Add the semicolon at the end of the previous statement
unexpected ")" Too many closing parentheses or a missing opening one Count the ( and ) in the surrounding function call
unexpected "}" Extra closing brace, or missing one earlier Match the braces from the outside in
unexpected end of file Missing } to close a function or class Add the closing brace at the very end of the broken block
unexpected "<" PHP file contains HTML outside <?php ?> tags, or <?php is missing Wrap the PHP section in <?php ... ?> correctly

Save, reload the site, and watch debug.log. If a new error appears pointing to a different line, you have uncovered the next problem: fix that one too. Repeat until the site loads.

You will know it worked when debug.log stops growing and the site loads normally on a hard refresh.

When to escalate

If you have tried recovery mode, reverting the file, and fixing it by hand, and the site is still broken, it is time to ask for help. Collect the following before you open a ticket with your host, your developer, or your managed WordPress provider:

  • The exact parse error text, copied verbatim from debug.log or the browser. Include the full file path and line number.
  • Your WordPress version, PHP version (visible in Tools → Site Health → Info → Server if you can reach the dashboard, or in the hosting panel), and active theme name.
  • The plugin or theme that broke, and the version before and after the change if you know.
  • A list of what you already tried from this article (recovery email, revert, direct fix).
  • The last 50 lines of wp-content/debug.log from the past hour.
  • The matching PHP error log entry from your hosting control panel for the same timestamp.

A support engineer with all of that can usually diagnose a parse error in under five minutes. Without it, they have to ask you for the same details one at a time, which drags a ten-minute fix out to a day.

How to avoid the next one

  • Never edit PHP from the WordPress admin editor. The in-dashboard file editor (Appearance → Theme File Editor, Plugins → Plugin File Editor) saves instantly and has no safety net. One typo locks you out of wp-admin. Disable it entirely by adding define( 'DISALLOW_FILE_EDIT', true ); to wp-config.php.
  • Use a child theme for any code you write yourself. A child theme is a thin wrapper around your real theme. When you break it, you can rename the child-theme folder over SFTP and the parent theme takes over automatically. Your live site stays up while you fix the child.
  • Test in staging or local first. Local by WP Engine runs a full WordPress on your laptop in a couple of clicks. Every host worth paying for also offers one-click staging. Paste the snippet there first. If it crashes, it crashes somewhere nobody can see.
  • Use a real editor with PHP syntax highlighting. VS Code, PhpStorm, or Sublime Text will catch unbalanced brackets and missing semicolons as you type. They do not catch every mistake, but they catch the obvious ones.
  • Take a backup before every code change, every theme update, and every plugin update. Most managed hosts do this automatically on a daily basis, and some trigger a snapshot immediately before an update. Confirm yours does. A parse error is recoverable in ten seconds with a backup and in an hour without one.

Want this to stop being your problem?

If outages or errors keep repeating, the fix is often consistency: updates, backups and monitoring that don't get skipped.

See WordPress maintenance

Search this site

Start typing to search, or browse the knowledge base and blog.