diff --git a/src/wp-includes/class-wp-block-type.php b/src/wp-includes/class-wp-block-type.php
index 4247cccffa..6ffda95b4e 100644
--- a/src/wp-includes/class-wp-block-type.php
+++ b/src/wp-includes/class-wp-block-type.php
@@ -123,7 +123,7 @@ class WP_Block_Type {
 
 	/**
 	 * Validates attributes against the current block schema, populating
-	 * defaulted and missing values, and omitting unknown attributes.
+	 * defaulted and missing values.
 	 *
 	 * @since 5.0.0
 	 *
@@ -131,30 +131,41 @@ class WP_Block_Type {
 	 * @return array             Prepared block attributes.
 	 */
 	public function prepare_attributes_for_render( $attributes ) {
+		// If there are no attribute definitions for the block type, skip
+		// processing and return vebatim.
 		if ( ! isset( $this->attributes ) ) {
 			return $attributes;
 		}
 
-		$prepared_attributes = array();
-
-		foreach ( $this->attributes as $attribute_name => $schema ) {
-			$value = null;
-
-			if ( isset( $attributes[ $attribute_name ] ) ) {
-				$is_valid = rest_validate_value_from_schema( $attributes[ $attribute_name ], $schema );
-				if ( ! is_wp_error( $is_valid ) ) {
-					$value = rest_sanitize_value_from_schema( $attributes[ $attribute_name ], $schema );
-				}
+		foreach ( $attributes as $attribute_name => $value ) {
+			// If the attribute is not defined by the block type, it cannot be
+			// validated.
+			if ( ! isset( $this->attributes[ $attribute_name ] ) ) {
+				continue;
 			}
 
-			if ( is_null( $value ) && isset( $schema['default'] ) ) {
-				$value = $schema['default'];
-			}
+			$schema = $this->attributes[ $attribute_name ];
 
-			$prepared_attributes[ $attribute_name ] = $value;
+			// Validate value by JSON schema. An invalid value should revert to
+			// its default, if one exists. This occurs by virtue of the missing
+			// attributes loop immediately following. If there is not a default
+			// assigned, the attribute value should remain unset.
+			$is_valid = rest_validate_value_from_schema( $value, $schema );
+			if ( is_wp_error( $is_valid ) ) {
+				unset( $attributes[ $attribute_name ] );
+			}
 		}
 
-		return $prepared_attributes;
+		// Populate values of any missing attributes for which the block type
+		// defines a default.
+		$missing_schema_attributes = array_diff_key( $this->attributes, $attributes );
+		foreach ( $missing_schema_attributes as $attribute_name => $schema ) {
+			if ( isset( $schema['default'] ) ) {
+				$attributes[ $attribute_name ] = $schema['default'];
+			}
+		}
+
+		return $attributes;
 	}
 
 	/**
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php
index f0e1e7db47..681e519313 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php
@@ -61,6 +61,7 @@ class WP_REST_Block_Renderer_Controller extends WP_REST_Controller {
 								'type'                 => 'object',
 								'additionalProperties' => false,
 								'properties'           => $block_type->get_attributes(),
+								'default'              => array(),
 							),
 							'post_id'    => array(
 								'description' => __( 'ID of the post context.' ),
diff --git a/tests/phpunit/tests/blocks/block-type.php b/tests/phpunit/tests/blocks/block-type.php
index ba80ab69a9..63e0809a13 100644
--- a/tests/phpunit/tests/blocks/block-type.php
+++ b/tests/phpunit/tests/blocks/block-type.php
@@ -168,7 +168,8 @@ class WP_Test_Block_Type extends WP_UnitTestCase {
 			'wrongType'          => 5,
 			'wrongTypeDefaulted' => 5,
 			/* missingDefaulted */
-			'undefined'          => 'omit',
+			'undefined'          => 'include',
+			'intendedNull'       => null,
 		);
 
 		$block_type = new WP_Block_Type(
@@ -189,6 +190,10 @@ class WP_Test_Block_Type extends WP_UnitTestCase {
 						'type'    => 'string',
 						'default' => 'define',
 					),
+					'intendedNull'       => array(
+						'type'    => array( 'string', 'null' ),
+						'default' => 'wrong',
+					),
 				),
 			)
 		);
@@ -198,14 +203,29 @@ class WP_Test_Block_Type extends WP_UnitTestCase {
 		$this->assertEquals(
 			array(
 				'correct'            => 'include',
-				'wrongType'          => null,
+				/* wrongType */
 				'wrongTypeDefaulted' => 'defaulted',
 				'missingDefaulted'   => 'define',
+				'undefined'          => 'include',
+				'intendedNull'       => null,
 			),
 			$prepared_attributes
 		);
 	}
 
+	/**
+	 * @ticket 45145
+	 */
+	function test_prepare_attributes_none_defined() {
+		$attributes = array( 'exists' => 'keep' );
+
+		$block_type = new WP_Block_Type( 'core/dummy', array() );
+
+		$prepared_attributes = $block_type->prepare_attributes_for_render( $attributes );
+
+		$this->assertEquals( $attributes, $prepared_attributes );
+	}
+
 	/**
 	 * @ticket 45097
 	 */
diff --git a/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php b/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php
index 472e448b10..dbc094ce98 100644
--- a/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php
@@ -319,7 +319,9 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca
 		$block_type = WP_Block_Type_Registry::get_instance()->get_registered( self::$block_name );
 		$defaults   = array();
 		foreach ( $block_type->attributes as $key => $attribute ) {
-			$defaults[ $key ] = isset( $attribute['default'] ) ? $attribute['default'] : null;
+			if ( isset( $attribute['default'] ) ) {
+				$defaults[ $key ] = $attribute['default'];
+			}
 		}
 
 		$request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name );
diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js
index 87dddb8186..e2c8e8f5c7 100644
--- a/tests/qunit/fixtures/wp-api-generated.js
+++ b/tests/qunit/fixtures/wp-api-generated.js
@@ -4317,6 +4317,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/block block",
                             "type": "object"
                         },
@@ -4356,6 +4357,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/latest-comments block",
                             "type": "object"
                         },
@@ -4395,6 +4397,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/archives block",
                             "type": "object"
                         },
@@ -4434,6 +4437,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/categories block",
                             "type": "object"
                         },
@@ -4473,6 +4477,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/latest-posts block",
                             "type": "object"
                         },
@@ -4512,6 +4517,7 @@ mockedApiResponse.Schema = {
                         },
                         "attributes": {
                             "required": false,
+                            "default": [],
                             "description": "Attributes for core/shortcode block",
                             "type": "object"
                         },