This was too much to put as a comment, I shall remove this later or replace it with a solution. @Cristian, could you try the following: function my_meta_save($post_id) { // verify this is not an auto save routine. if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; //Verify nonce if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__)) wp_die('Nonce check failure'); if ($_POST['post_type'] == 'page'){ if (!current_user_can('edit_page', $post_id)) wp_die('Permission check failure'); } $current_data = get_post_meta($post_id, '_my_meta', TRUE); $new_data = $_POST['_my_meta']; echo 'current data:' echo '<pre>'; var_dump($current_data); echo '</pre>'; echo 'sent data:'; echo '<pre>'; var_dump($new_data); echo '<pre>'; //my_meta_clean($new_data); Ignore this while debugging if ($current_data) { var_dump('Current data'); if (is_null($new_data)) $ret =delete_post_meta($post_id,'_my_meta'); else $ret = update_post_meta($post_id,'_my_meta',$new_data); } elseif (!is_null($new_data)) { $ret = add_post_meta($post_id,'_my_meta',$new_data,TRUE); }else{ wp_die('no data recieved'); } wp_die('success:'.$ret); return $post_id; } *Not tested*