Make WordPress Core

#64017 closed defect (bug) (worksforme)

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

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

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
13 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
13 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 13 months ago by westonruter (previous) (diff)

#3 @wwccscorer
13 months ago

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

#4 @wwccscorer
13 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 13 months ago by westonruter (previous) (diff)

#5 @westonruter
13 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
13 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
13 months ago

  • Milestone Awaiting Review
  • Resolution → worksforme
  • Status new → closed

Thanks for taking the time to report in any case!

Note: See TracTickets for help on using tickets.