I am trying to preserve old value of form when it fails the validation defined in sanitize callback of register_setting. But it does not do so, instead it save the default values

register_setting('setting-wpse3401', 'wpse3401_options', array( 'sanitize_callback' => [$this, 'wpse3401_sanitize_value']));

public function wpse3401_sanitize_value( $val )
    $newval = array();
    $type = 'updated';
    $msg = 'Settings is saved!';    

    $newval['form_field_0'] = sanitize_text_field($val['form_field_0']);
    if( $val['form_field_1'] < 1 ) {
        $type = 'error';
        $msg = 'Please enter number greater than 0'
    } else {
        $newval['form_field_1'] = $val['form_field_1'];

    add_settings_error('wpse3401_messages', 'wpse3401_message', __($msg, 'text-domain'), $type);

    if($type == 'updated'){
        return $newval;
    } else{
        return null;
  • Still no answer ? I am missing something ? – sanjay ojha Jun 16 '17 at 8:29

Unfortunately WordPress does not provide the old value as an additional argument to your sanitize_callback callable. This is supported in general by the option validator hook that WordPress calls when saving the updated setting...

return apply_filters( "sanitize_option_{$option}", $value, $option, $original_value );

...but in practice it is not actually registered with any additional arguments when the filter is added during register_setting:

if ( ! empty( $args['sanitize_callback'] ) ) {
    add_filter( "sanitize_option_{$option_name}", $args['sanitize_callback'] );

Because add_filter doesn't specify that the callable takes any additional arguments, apply_filter does not provide $option or $original_value to your callback when it is called (I consider this to be a bug, and have submitted a ticket to the developers). This means you cannot use the $original_value to fall back on when the provided setting is invalid. Instead, I suggest you just grab the current setting's value within your callback:

if ( 'updated' === $type ) {
    return $newval;
} else {
    // use previous value
    return get_option( 'wpse3401_options' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.