The only data closest to an explanation provided in the own documentation is that the change works if the record comes from a "derived" table, as in the example below, and that this is due to the fact that the derived data is materialized in a temporary table:
UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t ...) AS dt ...);
Extrapolating from this information, this behavior can be a result of the need to avoid conflicting locks. An UPDATE from a SELECT becomes impossible because the engine does not allow to obtain exclusive lock for a record that is already with read lock in another transaction.
Thinking this way, the example above works because, when faced with a "sub-subselect", the optimizer decides materialize query in temporary table: the record that receives read lock is a copy, in another location, of the one that will receive exclusive lock to UPDATE, avoiding conflict.
That said, I recognize that this picture I created does not make much sense = /. The InnoDB documentation is well detailed when stressing that the engine supports multiversioning of tuples and the four levels of lock isolation, you do not have to do this type of operation normally as in PostgreSQL, Oracle, and the like. I can only believe that this is a remnant of MyISAM implementation since pre-versions 5.5.5, since the only type of lock supported by this engine is the whole table.