diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
index 2749b12..405fc91 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
@@ -594,7 +594,6 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
 			'description'       => __( 'Limit result set to attachments of a particular media type.' ),
 			'type'              => 'string',
 			'enum'              => array_keys( $media_types ),
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$params['mime_type'] = array(
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
index 3454dc1..fc081f9 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
@@ -1102,9 +1102,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 					'type'         => 'string',
 					'format'       => 'ipv4',
 					'context'      => array( 'edit' ),
-					'arg_options'  => array(
-						'default'           => '127.0.0.1',
-					),
+					'default'      => '127.0.0.1',
 				),
 				'author_name'     => array(
 					'description'  => __( 'Display name for the object author.' ),
@@ -1176,17 +1174,13 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 					'description'  => __( 'The id for the parent of the object.' ),
 					'type'         => 'integer',
 					'context'      => array( 'view', 'edit', 'embed' ),
-					'arg_options'  => array(
-						'default'           => 0,
-					),
+					'default'      => 0,
 				),
 				'post'             => array(
 					'description'  => __( 'The id of the associated post object.' ),
 					'type'         => 'integer',
 					'context'      => array( 'view', 'edit' ),
-					'arg_options'  => array(
-						'default'           => 0,
-					),
+					'default'      => 0,
 				),
 				'status'           => array(
 					'description'  => __( 'State of the object.' ),
@@ -1252,26 +1246,28 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 			'description'       => __( 'Limit response to resources published after a given ISO8601 compliant date.' ),
 			'type'              => 'string',
 			'format'            => 'date-time',
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$query_params['author'] = array(
 			'description'       => __( 'Limit result set to comments assigned to specific user ids. Requires authorization.' ),
-			'sanitize_callback' => 'wp_parse_id_list',
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 		);
 
 		$query_params['author_exclude'] = array(
 			'description'       => __( 'Ensure result set excludes comments assigned to specific user ids. Requires authorization.' ),
-			'sanitize_callback' => 'wp_parse_id_list',
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 		);
 
 		$query_params['author_email'] = array(
 			'default'           => null,
 			'description'       => __( 'Limit result set to that from a specific author email. Requires authorization.' ),
 			'format'            => 'email',
-			'sanitize_callback' => 'sanitize_email',
 			'type'              => 'string',
 		);
 
@@ -1279,43 +1275,40 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 			'description'       => __( 'Limit response to resources published before a given ISO8601 compliant date.' ),
 			'type'              => 'string',
 			'format'            => 'date-time',
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$query_params['exclude'] = array(
 			'description'        => __( 'Ensure result set excludes specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		$query_params['include'] = array(
 			'description'        => __( 'Limit result set to specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		$query_params['karma'] = array(
 			'default'           => null,
 			'description'       => __( 'Limit result set to that of a particular comment karma. Requires authorization.' ),
-			'sanitize_callback' => 'absint',
 			'type'              => 'integer',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['offset'] = array(
 			'description'        => __( 'Offset the result set by a specific number of comments.' ),
 			'type'               => 'integer',
-			'sanitize_callback'  => 'absint',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['order']      = array(
 			'description'           => __( 'Order sort attribute ascending or descending.' ),
 			'type'                  => 'string',
-			'sanitize_callback'     => 'sanitize_key',
-			'validate_callback'     => 'rest_validate_request_arg',
 			'default'               => 'desc',
 			'enum'                  => array(
 				'asc',
@@ -1326,8 +1319,6 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 		$query_params['orderby']    = array(
 			'description'           => __( 'Sort collection by object attribute.' ),
 			'type'                  => 'string',
-			'sanitize_callback'     => 'sanitize_key',
-			'validate_callback'     => 'rest_validate_request_arg',
 			'default'               => 'date_gmt',
 			'enum'                  => array(
 				'date',
@@ -1343,22 +1334,28 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 		$query_params['parent'] = array(
 			'default'           => array(),
 			'description'       => __( 'Limit result set to resources of specific parent ids.' ),
-			'sanitize_callback' => 'wp_parse_id_list',
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 		);
 
 		$query_params['parent_exclude'] = array(
 			'default'           => array(),
 			'description'       => __( 'Ensure result set excludes specific parent ids.' ),
-			'sanitize_callback' => 'wp_parse_id_list',
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 		);
 
 		$query_params['post']   = array(
 			'default'           => array(),
 			'description'       => __( 'Limit result set to resources assigned to specific post ids.' ),
 			'type'              => 'array',
-			'sanitize_callback' => 'wp_parse_id_list',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 		);
 
 		$query_params['status'] = array(
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 0122f9a..723fc95 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
@@ -1975,20 +1975,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 				'items'       => array(
 					'type'    => 'integer',
 				),
-				'arg_options' => array(
-					'sanitize_callback' => 'wp_parse_id_list',
-				),
-				'context'     => array( 'view', 'edit' ),
-			);
-			$schema['properties'][ $base . '_exclude' ] = array(
-				'description' => sprintf( __( 'The terms in the %s taxonomy that should not be assigned to the object.' ), $taxonomy->name ),
-				'type'        => 'array',
-				'items'       => array(
-					'type'    => 'integer',
-				),
-				'arg_options' => array(
-					'sanitize_callback' => 'wp_parse_id_list',
-				),
 				'context'     => array( 'view', 'edit' ),
 			);
 		}
@@ -2013,21 +1999,24 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			'description'        => __( 'Limit response to resources published after a given ISO8601 compliant date.' ),
 			'type'               => 'string',
 			'format'             => 'date-time',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		if ( post_type_supports( $this->post_type, 'author' ) ) {
 			$params['author'] = array(
 				'description'         => __( 'Limit result set to posts assigned to specific authors.' ),
 				'type'                => 'array',
+				'items'               => array(
+					'type'            => 'integer',
+				),
 				'default'             => array(),
-				'sanitize_callback'   => 'wp_parse_id_list',
 			);
 			$params['author_exclude'] = array(
 				'description'         => __( 'Ensure result set excludes posts assigned to specific authors.' ),
 				'type'                => 'array',
+				'items'               => array(
+					'type'            => 'integer',
+				),
 				'default'             => array(),
-				'sanitize_callback'   => 'wp_parse_id_list',
 			);
 		}
 
@@ -2035,37 +2024,36 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			'description'        => __( 'Limit response to resources published before a given ISO8601 compliant date.' ),
 			'type'               => 'string',
 			'format'             => 'date-time',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$params['exclude'] = array(
 			'description'        => __( 'Ensure result set excludes specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		$params['include'] = array(
 			'description'        => __( 'Limit result set to specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
 			$params['menu_order'] = array(
 				'description'        => __( 'Limit result set to resources with a specific menu_order value.' ),
 				'type'               => 'integer',
-				'sanitize_callback'  => 'absint',
-				'validate_callback'  => 'rest_validate_request_arg',
 			);
 		}
 
 		$params['offset'] = array(
 			'description'        => __( 'Offset the result set by a specific number of items.' ),
 			'type'               => 'integer',
-			'sanitize_callback'  => 'absint',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$params['order'] = array(
@@ -2073,7 +2061,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			'type'               => 'string',
 			'default'            => 'desc',
 			'enum'               => array( 'asc', 'desc' ),
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$params['orderby'] = array(
@@ -2088,7 +2075,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 				'title',
 				'slug',
 			),
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
@@ -2101,13 +2087,17 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			$params['parent'] = array(
 				'description'       => __( 'Limit result set to those of particular parent ids.' ),
 				'type'              => 'array',
-				'sanitize_callback' => 'wp_parse_id_list',
+				'items'             => array(
+					'type'          => 'integer',
+				),
 				'default'           => array(),
 			);
 			$params['parent_exclude'] = array(
 				'description'       => __( 'Limit result set to all items except those of a particular parent id.' ),
 				'type'              => 'array',
-				'sanitize_callback' => 'wp_parse_id_list',
+				'items'             => array(
+					'type'          => 'integer',
+				),
 				'default'           => array(),
 			);
 		}
@@ -2135,7 +2125,18 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			$params[ $base ] = array(
 				'description'       => sprintf( __( 'Limit result set to all items that have the specified term assigned in the %s taxonomy.' ), $base ),
 				'type'              => 'array',
-				'sanitize_callback' => 'wp_parse_id_list',
+				'items'             => array(
+					'type'          => 'integer',
+				),
+				'default'           => array(),
+			);
+
+			$params[ $base . '_exclude' ] = array(
+				'description' => sprintf( __( 'Limit result set to all items except those that have the specified term assigned in the %s taxonomy.' ), $base ),
+				'type'        => 'array',
+				'items'       => array(
+					'type'    => 'integer',
+				),
 				'default'           => array(),
 			);
 		}
@@ -2144,7 +2145,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 			$params['sticky'] = array(
 				'description'       => __( 'Limit result set to items that are sticky.' ),
 				'type'              => 'boolean',
-				'sanitize_callback' => 'rest_parse_request_arg',
 			);
 		}
 
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php
index 98a5e21..0f253a4 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php
@@ -301,7 +301,6 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
 		$new_params['type'] = array(
 			'description'  => __( 'Limit results to resources associated with a specific post type.' ),
 			'type'         => 'string',
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 		return $new_params;
 	}
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
index ceaa26b..c9f9f91 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
@@ -887,42 +887,41 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
 		$query_params['exclude'] = array(
 			'description'       => __( 'Ensure result set excludes specific ids.' ),
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 			'default'           => array(),
-			'sanitize_callback' => 'wp_parse_id_list',
 		);
 
 		$query_params['include'] = array(
 			'description'       => __( 'Limit result set to specific ids.' ),
 			'type'              => 'array',
+			'items'             => array(
+				'type'          => 'integer',
+			),
 			'default'           => array(),
-			'sanitize_callback' => 'wp_parse_id_list',
 		);
 
 		if ( ! $taxonomy->hierarchical ) {
 			$query_params['offset'] = array(
 				'description'       => __( 'Offset the result set by a specific number of items.' ),
 				'type'              => 'integer',
-				'sanitize_callback' => 'absint',
-				'validate_callback' => 'rest_validate_request_arg',
 			);
 		}
 
 		$query_params['order'] = array(
 			'description'       => __( 'Order sort attribute ascending or descending.' ),
 			'type'              => 'string',
-			'sanitize_callback' => 'sanitize_key',
 			'default'           => 'asc',
 			'enum'              => array(
 				'asc',
 				'desc',
 			),
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$query_params['orderby'] = array(
 			'description'       => __( 'Sort collection by resource attribute.' ),
 			'type'              => 'string',
-			'sanitize_callback' => 'sanitize_key',
 			'default'           => 'name',
 			'enum'              => array(
 				'id',
@@ -933,23 +932,18 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
 				'description',
 				'count',
 			),
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$query_params['hide_empty'] = array(
 			'description'       => __( 'Whether to hide resources not assigned to any posts.' ),
 			'type'              => 'boolean',
 			'default'           => false,
-			'sanitize_callback' => 'rest_sanitize_request_arg',
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		if ( $taxonomy->hierarchical ) {
 			$query_params['parent'] = array(
 				'description'       => __( 'Limit result set to resources assigned to a specific parent.' ),
 				'type'              => 'integer',
-				'sanitize_callback' => 'absint',
-				'validate_callback' => 'rest_validate_request_arg',
 			);
 		}
 
@@ -957,13 +951,11 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
 			'description'       => __( 'Limit result set to resources assigned to a specific post.' ),
 			'type'              => 'integer',
 			'default'           => null,
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		$query_params['slug'] = array(
 			'description'       => __( 'Limit result set to resources with a specific slug.' ),
 			'type'              => 'string',
-			'validate_callback' => 'rest_validate_request_arg',
 		);
 
 		return $query_params;
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
index bb3737d..1256c68 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
@@ -1102,9 +1102,6 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
 						'type'    => 'string',
 					),
 					'context'     => array( 'edit' ),
-					'arg_options' => array(
-						'sanitize_callback' => 'wp_parse_slug_list',
-					),
 				),
 				'password'        => array(
 					'description' => __( 'Password for the resource (never included).' ),
@@ -1171,31 +1168,31 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
 		$query_params['exclude'] = array(
 			'description'        => __( 'Ensure result set excludes specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		$query_params['include'] = array(
 			'description'        => __( 'Limit result set to specific ids.' ),
 			'type'               => 'array',
+			'items'              => array(
+				'type'           => 'integer',
+			),
 			'default'            => array(),
-			'sanitize_callback'  => 'wp_parse_id_list',
 		);
 
 		$query_params['offset'] = array(
 			'description'        => __( 'Offset the result set by a specific number of items.' ),
 			'type'               => 'integer',
-			'sanitize_callback'  => 'absint',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['order'] = array(
 			'default'            => 'asc',
 			'description'        => __( 'Order sort attribute ascending or descending.' ),
 			'enum'               => array( 'asc', 'desc' ),
-			'sanitize_callback'  => 'sanitize_key',
 			'type'               => 'string',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['orderby'] = array(
@@ -1210,21 +1207,20 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
 				'email',
 				'url',
 			),
-			'sanitize_callback'  => 'sanitize_key',
 			'type'               => 'string',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['slug']    = array(
 			'description'        => __( 'Limit result set to resources with a specific slug.' ),
 			'type'               => 'string',
-			'validate_callback'  => 'rest_validate_request_arg',
 		);
 
 		$query_params['roles']   = array(
 			'description'        => __( 'Limit result set to resources matching at least one specific role provided. Accepts csv list or single role.' ),
 			'type'               => 'array',
-			'sanitize_callback'  => 'wp_parse_slug_list',
+			'items'              => array(
+				'type'           => 'string',
+			),
 		);
 
 		return $query_params;
diff --git a/tests/phpunit/tests/rest-api/rest-categories-controller.php b/tests/phpunit/tests/rest-api/rest-categories-controller.php
index 440cb45..4212f5f 100644
--- a/tests/phpunit/tests/rest-api/rest-categories-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-categories-controller.php
@@ -428,6 +428,15 @@ class WP_Test_REST_Categories_Controller extends WP_Test_REST_Controller_Testcas
 		$this->assertEquals( 'Child', $data[0]['name'] );
 	}
 
+	public function test_get_terms_invalid_parent_arg() {
+		$category1 = $this->factory->category->create( array( 'name' => 'Parent' ) );
+		$this->factory->category->create( array( 'name' => 'Child', 'parent' => $category1 ) );
+		$request = new WP_REST_Request( 'GET', '/wp/v2/categories' );
+		$request->set_param( 'parent', 'invalid-parent' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
 	public function test_get_terms_private_taxonomy() {
 		register_taxonomy( 'robin', 'post', array( 'public' => false ) );
 		$this->factory->term->create( array( 'name' => 'Cape', 'taxonomy' => 'robin' ) );
diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php
index 8dc8c4c..6e8c89f 100644
--- a/tests/phpunit/tests/rest-api/rest-comments-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php
@@ -300,6 +300,15 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( $id3, $data[0]['id'] );
+		// Orderby=>invalid should fail
+		$request->set_param( 'orderby', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+		// fails on invalid id
+		$request->set_param( 'orderby', array( 'include' ) );
+		$request->set_param( 'include', array( 'invalid' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_exclude_query() {
@@ -320,6 +329,11 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$data = $response->get_data();
 		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ), true ) );
 		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ), true ) );
+
+		// fails on invalid id
+		$request->set_param( 'exclude', array( 'invalid' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_offset_query() {
@@ -343,6 +357,10 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$request->set_param( 'page', 3 );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 2, $response->get_data() );
+		// 'offset' with invalid value errors
+		$request->set_param( 'offset', 'moreplease' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_order_query() {
@@ -364,6 +382,10 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$response = $this->server->dispatch( $request );
 		$data = $response->get_data();
 		$this->assertEquals( self::$approved_id, $data[0]['id'] );
+		// order=>asc,id should fail
+		$request->set_param( 'order', 'asc,id' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_private_post_no_permissions() {
@@ -402,8 +424,13 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$this->assertEquals( 200, $response->get_status() );
 		$comments = $response->get_data();
 		$this->assertCount( 2, $comments );
+		// Invalid author param errors
+		$request->set_param( 'author', 'skippy' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 		// Unavailable to unauthenticated; defaults to error
 		wp_set_current_user( 0 );
+		$request->set_param( 'author', array( self::$author_id, self::$subscriber_id ) );
 		$response = $this->server->dispatch( $request );
 		$this->assertErrorResponse( 'rest_forbidden_param', $response, 401 );
 	}
@@ -441,8 +468,14 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$this->assertEquals( 200, $response->get_status() );
 		$comments = $response->get_data();
 		$this->assertCount( 2, $comments );
+		// 'author_exclude' for both invalid author
+		$request = new WP_REST_Request( 'GET', '/wp/v2/comments' );
+		$request->set_param( 'author_exclude', 'skippy' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 		// Unavailable to unauthenticated; defaults to error
 		wp_set_current_user( 0 );
+		$request->set_param( 'author_exclude', array( self::$author_id, self::$subscriber_id ) );
 		$response = $this->server->dispatch( $request );
 		$this->assertErrorResponse( 'rest_forbidden_param', $response, 401 );
 	}
@@ -470,6 +503,10 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$request->set_param( 'parent', array( $parent_id, $parent_id2 ) );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 2, $response->get_data() );
+		// Invalid parent should error
+		$request->set_param( 'parent', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_parent_exclude_arg() {
@@ -495,6 +532,10 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$request->set_param( 'parent_exclude', array( $parent_id, $parent_id2 ) );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 3, $response->get_data() );
+		// Invalid parent id should error
+		$request->set_param( 'parent_exclude', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_search_query() {
@@ -957,6 +998,28 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$this->assertEquals( $comment_id, $collection_data[0]['id'] );
 	}
 
+	public function test_create_comment_invalid_email() {
+		$post_id = $this->factory->post->create();
+		wp_set_current_user( self::$admin_id );
+
+		$params = array(
+			'post'	=> $post_id,
+			'author'	   => self::$admin_id,
+			'author_name'  => 'Comic Book Guy',
+			'author_email' => 'hello:)',
+			'author_url'   => 'http://androidsdungeon.com',
+			'content' => 'Worst Comment Ever!',
+			'date'	=> '2014-11-07T10:14:25',
+		);
+
+		$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $params ) );
+
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
 	public function test_create_item_current_user() {
 		$user_id = $this->factory->user->create( array(
 			'role' => 'subscriber',
@@ -1057,6 +1120,47 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$this->assertErrorResponse( 'rest_comment_invalid_karma', $response, 403 );
 	}
 
+	public function test_create_comment_invalid_post() {
+		wp_set_current_user( self::$subscriber_id );
+
+		$params = array(
+			'post'		   => 'some-slug',
+			'author_name'  => 'Homer Jay Simpson',
+			'author_email' => 'chunkylover53@aol.com',
+			'author_url'   => 'http://compuglobalhypermeganet.com',
+			'content'	   => 'Here\’s to alcohol: the cause of, and solution to, all of life\’s problems.',
+			'author'	   => self::$subscriber_id,
+		);
+
+		$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $params ) );
+		$response = $this->server->dispatch( $request );
+
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
+	public function test_create_comment_karma_invalid_value() {
+		wp_set_current_user( self::$subscriber_id );
+
+		$params = array(
+			'post'		 => self::$post_id,
+			'author_name'  => 'Homer Jay Simpson',
+			'author_email' => 'chunkylover53@aol.com',
+			'author_url'   => 'http://compuglobalhypermeganet.com',
+			'content'	  => 'Here\’s to alcohol: the cause of, and solution to, all of life\’s problems.',
+			'author'	   => self::$subscriber_id,
+			'karma'		=> 'themostkarmaever',
+		);
+
+		$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $params ) );
+		$response = $this->server->dispatch( $request );
+
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
 	public function test_create_comment_status_without_permission() {
 		wp_set_current_user( self::$subscriber_id );
 
@@ -1726,6 +1830,10 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase
 		$this->assertArrayHasKey( 'post', $properties );
 		$this->assertArrayHasKey( 'status', $properties );
 		$this->assertArrayHasKey( 'type', $properties );
+
+		$this->assertEquals( '127.0.0.1', $properties['author_ip']['default'] );
+		$this->assertEquals( 0, $properties['parent']['default'] );
+		$this->assertEquals( 0, $properties['post']['default'] );
 	}
 
 	public function test_get_item_schema_show_avatar() {
diff --git a/tests/phpunit/tests/rest-api/rest-pages-controller.php b/tests/phpunit/tests/rest-api/rest-pages-controller.php
index 2ce9afe..a571803 100644
--- a/tests/phpunit/tests/rest-api/rest-pages-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-pages-controller.php
@@ -95,6 +95,10 @@ class WP_Test_REST_Pages_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$data = $response->get_data();
 		$this->assertEquals( 1, count( $data ) );
 		$this->assertEquals( $id2, $data[0]['id'] );
+		// Invalid parent should fail
+		$request->set_param( 'parent', 'some-slug' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_parents_query() {
@@ -129,6 +133,10 @@ class WP_Test_REST_Pages_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$data = $response->get_data();
 		$this->assertEquals( 1, count( $data ) );
 		$this->assertEquals( $id1, $data[0]['id'] );
+		// Invalid parent_exclude should error
+		$request->set_param( 'parent_exclude', 'some-slug' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_menu_order_query() {
@@ -156,6 +164,11 @@ class WP_Test_REST_Pages_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$this->assertEquals( $id4, $data[1]['id'] );
 		$this->assertEquals( $id2, $data[2]['id'] );
 		$this->assertEquals( $id3, $data[3]['id'] );
+		// Invalid menu_order should fail
+		$request = new WP_REST_Request( 'GET', '/wp/v2/pages' );
+		$request->set_param( 'menu_order', 'top-first' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_min_max_pages_query() {
diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php
index dcebfe8..e489667 100644
--- a/tests/phpunit/tests/rest-api/rest-posts-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php
@@ -92,6 +92,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 			'author_exclude',
 			'before',
 			'categories',
+			'categories_exclude',
 			'context',
 			'exclude',
 			'include',
@@ -105,6 +106,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 			'status',
 			'sticky',
 			'tags',
+			'tags_exclude',
 			), $keys );
 	}
 
@@ -183,6 +185,11 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertNotEquals( self::$editor_id, $data[0]['author'] );
 		$this->assertNotEquals( self::$editor_id, $data[1]['author'] );
+		// invalid author_exclude errors
+		$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
+		$request->set_param( 'author_exclude', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_include_query() {
@@ -202,6 +209,11 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( $id1, $data[0]['id'] );
+		// Invalid include should error
+		$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
+		$request->set_param( 'include', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_exclude_query() {
@@ -224,6 +236,10 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$data = $response->get_data();
 		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ), true ) );
 		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ), true ) );
+
+		$request->set_param( 'exclude', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_search_query() {
@@ -352,6 +368,15 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$response = $this->server->dispatch( $request );
 		$data = $response->get_data();
 		$this->assertEquals( 'Apple Cobbler', $data[0]['title']['rendered'] );
+		// order=>asc,id should fail
+		$request->set_param( 'order', 'asc,id' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+		// orderby=>content should fail (invalid param test)
+		$request->set_param( 'order', 'asc' );
+		$request->set_param( 'orderby', 'content' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_with_orderby_relevance() {
@@ -402,6 +427,10 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$request->set_param( 'page', 3 );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 2, $response->get_data() );
+		// Invalid 'offset' should error
+		$request->set_param( 'offset', 'moreplease' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_tags_query() {
@@ -458,6 +487,10 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 1, $response->get_data() );
+
+		$request->set_param( 'tags', array( 'my-tag' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_tags_and_categories_exclude_query() {
@@ -480,6 +513,10 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$data = $response->get_data();
 		$this->assertCount( 1, $data );
 		$this->assertEquals( $id2, $data[0]['id'] );
+
+		$request->set_param( 'tags_exclude', array( 'my-tag' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_sticky_query() {
@@ -497,6 +534,10 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$posts = $response->get_data();
 		$post = $posts[0];
 		$this->assertEquals( $id2, $post['id'] );
+
+		$request->set_param( 'sticky', 'nothanks' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_sticky_with_post__in_query() {
@@ -1935,7 +1976,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$response = $this->server->dispatch( $request );
 		$data = $response->get_data();
 		$properties = $data['schema']['properties'];
-		$this->assertEquals( 25, count( $properties ) );
+		$this->assertEquals( 23, count( $properties ) );
 		$this->assertArrayHasKey( 'author', $properties );
 		$this->assertArrayHasKey( 'comment_status', $properties );
 		$this->assertArrayHasKey( 'content', $properties );
@@ -1958,9 +1999,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te
 		$this->assertArrayHasKey( 'title', $properties );
 		$this->assertArrayHasKey( 'type', $properties );
 		$this->assertArrayHasKey( 'tags', $properties );
-		$this->assertArrayHasKey( 'tags_exclude', $properties );
 		$this->assertArrayHasKey( 'categories', $properties );
-		$this->assertArrayHasKey( 'categories_exclude', $properties );
 	}
 
 	public function test_get_additional_field_registration() {
diff --git a/tests/phpunit/tests/rest-api/rest-tags-controller.php b/tests/phpunit/tests/rest-api/rest-tags-controller.php
index 0bdae85..568b15a 100644
--- a/tests/phpunit/tests/rest-api/rest-tags-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-tags-controller.php
@@ -98,6 +98,10 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( 'Season 5', $data[0]['name'] );
 		$this->assertEquals( 'The Be Sharps', $data[1]['name'] );
+		// invalid value should fail
+		$request->set_param( 'hide_empty', 'nothanks' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_include_query() {
@@ -117,6 +121,10 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( $id3, $data[0]['id'] );
+		// Include invalid value shoud fail
+		$request->set_param( 'include', array( 'myterm' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_exclude_query() {
@@ -132,6 +140,10 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ), true ) );
 		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ), true ) );
+		// Invalid exclude value should fail
+		$request->set_param( 'exclude', array( 'invalid' ) );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_offset_query() {
@@ -151,6 +163,10 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$request->set_param( 'page', 3 );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 2, $response->get_data() );
+		// 'offset' invalid value shoudl fail
+		$request->set_param( 'offset', 'moreplease' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 
@@ -181,6 +197,10 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( 'Apple', $data[0]['name'] );
+		// Invalid orderby should fail.
+		$request->set_param( 'orderby', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_orderby_id() {
@@ -231,6 +251,12 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( 'DC', $data[0]['name'] );
+
+		// Invalid post should error.
+		$request = new WP_REST_Request( 'GET', '/wp/v2/tags' );
+		$request->set_param( 'post', 'invalid-post' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_terms_post_args_paging() {
diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php
index 4f89ac2..7dd2540 100644
--- a/tests/phpunit/tests/rest-api/rest-users-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-users-controller.php
@@ -363,6 +363,20 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
 		$this->assertErrorResponse( 'rest_forbidden_orderby', $response, 401 );
 	}
 
+	public function test_get_items_invalid_order() {
+		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
+		$request->set_param( 'order', 'asc,id' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
+	public function test_get_items_invalid_orderby() {
+		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
+		$request->set_param( 'orderby', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
+	}
+
 	public function test_get_items_offset() {
 		wp_set_current_user( self::$user );
 		// 2 users created in __construct(), plus default user
@@ -379,6 +393,10 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
 		$request->set_param( 'page', 3 );
 		$response = $this->server->dispatch( $request );
 		$this->assertCount( 2, $response->get_data() );
+		// 'offset' invalid value should error
+		$request->set_param( 'offset', 'moreplease' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_include_query() {
@@ -399,7 +417,12 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertEquals( 2, count( $data ) );
 		$this->assertEquals( $id3, $data[0]['id'] );
+		// Invalid include should fail
+		$request->set_param( 'include', 'invalid' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 		// No privileges
+		$request->set_param( 'include', array( $id3, $id1 ) );
 		wp_set_current_user( 0 );
 		$response = $this->server->dispatch( $request );
 		$data = $response->get_data();
@@ -421,6 +444,10 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
 		$data = $response->get_data();
 		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ), true ) );
 		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ), true ) );
+		// Invalid exlude value should error.
+		$request->set_param( 'exclude', 'none-of-those-please' );
+		$response = $this->server->dispatch( $request );
+		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
 	}
 
 	public function test_get_items_search() {
