“Illegal string offset” and “Cannot access offset of type string on string”: what they mean and the fix

By CompatNav · Published · Last reviewed · 3 min read

Short answer

Both messages mean the same thing: a plugin or theme reads an entry, like $options['color'], from a variable that holds a text, not a list, often a setting saved in an old format. PHP 7.4 wrote “Illegal string offset ‘color’” and went on with a wrong value: the first letter of the text. PHP 8 stops the page with “Uncaught TypeError: Cannot access offset of type string on string”. Switch PHP back if the site is down, update the plugin or theme, or send the message to its developer. The developer fix is to check that the value is a list before reading from it.

The message, on PHP 7.4 and PHP 8

A banner plugin reads its color from its options. On this site an old version saved the options as the text yes, not as a list:

wp-content/plugins/simple-banner/simple-banner.php

<?php
$options = 'yes'; // saved as text by an old version, not as a list of settings
echo 'Banner color: ', $options['color'], "\n";

Output on PHP 7.4.33

Banner color:
Warning: Illegal string offset 'color' in /var/www/html/wp-content/plugins/simple-banner/simple-banner.php on line 3
y

Output on PHP 8.0.30the script stopped

Banner color:
Fatal error: Uncaught TypeError: Cannot access offset of type string on string in /var/www/html/wp-content/plugins/simple-banner/simple-banner.php:3
Stack trace:
#0 {main}
  thrown in /var/www/html/wp-content/plugins/simple-banner/simple-banner.php on line 3

On PHP 7.4 the page continued, and printed “y” as the color: PHP took the first letter of yes. On PHP 8 the page stops.

php.net, in the PHP 8.0 changes, lists it with the warnings that became errors: “This E_WARNING to TypeError change also affects the E_WARNING “Illegal string offset ‘string’” for illegal string offsets.” (php.net)

What it means

$options['color'] asks for the entry color in a list. If $options is a text, PHP can only read its characters by number ($options[0] is the first letter). A word like color isn’t a position, so the read makes no sense. PHP 7.4 guessed position 0 and warned; PHP 8 refuses.

Because it depends on what’s stored, the same plugin can work on one site and stop on another, and the line in the message is fine in itself.

Fix it, in order

  1. Site down? Switch PHP back or pause the plugin: the critical error guide.
  2. Find the plugin or theme from the path in the message.
  3. Update it, then open its settings page and save the settings once: that can store them again in the format the code expects. Back up before.
  4. Still there? Send the full message to the developer, and mention the plugin version you came from.

Can a check find it before the upgrade?

Not by reading code, because the code is correct for the data it was written for. CompatNav reports nothing for the example above. Your PHP 7.4 error log can: “Illegal string offset” is a warning, which WordPress reports even with WP_DEBUG off (WordPress 7.1.2 source), so look for it in your host’s PHP error log. Each one is a fatal error on PHP 8. Finding PHP notices on real visits covers collecting them on a live site.

Related, but only warnings or notices: “Trying to access array offset on value of type null” and “Automatic conversion of false to array is deprecated”.

Key takeaways

  • PHP 7.4: “Warning: Illegal string offset ‘color’”, and the code continued with the text’s first letter.
  • PHP 8.0 and later: “Uncaught TypeError: Cannot access offset of type string on string”, a fatal error.
  • Same cause: the variable holds a text where the code expected a list of values.
  • It depends on the data, often an old or damaged setting, so only the error log shows it in advance.
  • The developer fix: if ( ! is_array( $options ) ) { $options = array(); } before reading.

Frequently asked questions

Why did it work on PHP 7.4?

It didn’t work, it only didn’t stop. PHP 7.4 read the first character of the text, warned, and continued with that wrong value; in our test a banner color came out as “y”. PHP 8 stops instead of guessing.

Where does a text instead of a list come from?

Often from a setting saved by an older version of the plugin, by an import, or by a migration that changed how it was stored. On one site the setting is fine, on another it isn’t, which is why the error appears on some sites only.

Can resetting the plugin’s settings fix it?

Sometimes: saving the plugin’s settings page again stores them in the expected format. Back up first, and if the error stays, contact the developer.

Check your own site before you upgrade

CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.

Get CompatNav on wordpress.org How it works

Sources

About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.