Make WordPress Core

Opened 6 months ago

Closed 6 months ago

#64017 closed defect (bug) (worksforme)

WordPress REST API returns 500 error when updating serialized meta with an unchanged value

Reported by: wwccscorer's profile wwccscorer Owned by:
Milestone: Priority: normal
Severity: normal Version: 6.8.2
Component: REST API Keywords:
Focuses: Cc:

Description

I am not sufficiently knowledgeable to describe this properly.
It is a problem I have on my dev website - research pointed out https://coreysalzano.com/wordpress/rest-api-returns-500-error-updating-serialized-meta/ which describes precisely what is happening.
The solution in the comments (https://inexi.com/wordpress-rest-api-returns-error-when-updating-quoted-json-data/) works for me and resolves the problem so I can only assume that the issue is as described by Corey Salzano in 2018.

Change History (7)

#1 @westonruter
6 months ago

  • Keywords reporter-feedback added

I just tried to replicate this issue but I was unable.

Here is the test plugin I used to test: https://gist.github.com/westonruter/3ad07c7604897821666a990f84e442fa

Can you share an example of the data you are storing in postmeta?

#2 @wwccscorer
6 months ago

This is the code which I use to enter the values for the meta data

registerPlugin( 'event-controls', {
        render: () => {
                // Add your custom code here.
                const postType = useSelect(
                        ( select ) => select( 'core/editor' ).getCurrentPostType(),
                        []
                );

                const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );

                if ( 'event' !== postType ) {
                        return null;
                }
                return (
                        <PluginDocumentSettingPanel
                                title={ 'Event info' }
                        >
                                <VStack>
                                        <InputControl
                                                label={ 'Event Date' }
                                                value={ meta?.event_date }
                                                placeholder={ 'YYYY-MM-DD' }
                                                onChange={ ( value ) => setMeta( {
                                                        ...meta,
                                                        event_date: value || null
                                                } ) }
                                        />
                                        <InputControl
                                                label={ 'Event start time' }
                                                value={ meta?.event_start_time }
                                                onChange={ ( value ) => setMeta( {
                                                        ...meta,
                                                        event_start_time: value || null
                                                } ) }
                                        />
                                        <InputControl
                                                label={ 'Course name' }
                                                placeholder={ 'Location-slug or title' }
                                                value={ meta?.course_name_slug }
                                                onChange={ ( value ) => setMeta( {
                                                        ...meta,
                                                        course_name_slug: value || null
                                                } ) }
                                        />
                                </VStack>
                        </PluginDocumentSettingPanel>
                );
        }
} );

This all works fine but when I click the save button on the editor page to save the whole page, if there are any unsaved changes I receive the 500 error.

Last edited 6 months ago by westonruter (previous) (diff)

#3 @wwccscorer
6 months ago

Sorry - that should have read "if there are any unchanged values to be saved I receive the 500 error"

#4 @wwccscorer
6 months ago

If it is of any use, below is the filter (taken from the second reference in the original ticket and modified appropriately for my metadata) which I use to prevent the problem from happening ;_

<?php
// Fix for WP REST API meta error when sending updated encoded JSON with no change
add_filter( 'update_post_metadata' , function ( $value , $object_id , $meta_key = false , $meta_value, $prev_value ) {

        $meta_type = 'post';

        $serialized_meta_keys = array('course_length',
                'course_minslope',
                'course_maxslope',
                'course_minelev',
                'course_maxelev',
                'course_ascent',
                'hq_name',
                'hq_address',
                'hq_postcode',
                'hq_link',
                'course_name_slug',
                'event_date',
                'event_start_time',
        );

        if ( defined('REST_REQUEST') && REST_REQUEST && in_array($meta_key, $serialized_meta_keys) ) {

                $meta_cache = wp_cache_get($object_id, $meta_type . '_meta');

                if ( !$meta_cache ) {
                        $meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
                        $meta_cache = $meta_cache[$object_id];
                }

                if ( isset($meta_cache[$meta_key]) ) {
                        if ( $meta_value === $meta_cache[$meta_key][0] ) return true;
                }

        }

        return $value;
}, 10 , 5 );
Last edited 6 months ago by westonruter (previous) (diff)

#5 @westonruter
6 months ago

So the error is happening when saving event_date, event_start_time, or course_name_slug meta keys? The values you're storing here don't seem to be anything but strings. They don't seem to need to be serialized to be stored in meta.

Without that update_post_metadata filter added, can you reproduce the 500 error and share the REST API payload and response? For example, in Chrome DevTools, in my example plugin I selected the POST request to update the posts endpoint, and the payload for me is:

{
  "meta": {
    "color_names_array": [
      "red",
      "green",
      "blue"
    ]
  }
}

And the response is JSON containing the entire post entity, including the meta I provided.

#6 @wwccscorer
6 months ago

  • Keywords reporter-feedback removed

I cannot reproduce the error on a clean install of WP 6.8.2 and I can no longer reproduce it on my dev site.

Since my attempts to investigate have unwittingly resolved the problem it is obvious that the fault lay somewhere in my code rather than in WP.

Please accept my apologies for wasting your time and close this ticket with the appropriate status for 'User was wrong' or 'User was incompetent' as you see fit.

#7 @westonruter
6 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

Thanks for taking the time to report in any case!

Note: See TracTickets for help on using tickets.