From 82e64645e2833716b3e5a61cf97f3814f471761f Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Mon, 10 Nov 2025 15:22:27 -0600 Subject: [PATCH 1/8] Ensure attributes is always an object, never null or undefined --- packages/blocks/src/store/process-block-type.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 04259be4d33d56..7249c0072716e5 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -103,6 +103,14 @@ export const processBlockType = ), }; + // Ensure attributes is always an object, never null or undefined. + if ( + ! blockType.attributes || + typeof blockType.attributes !== 'object' + ) { + blockType.attributes = {}; + } + const settings = applyFilters( 'blocks.registerBlockType', blockType, From 43a149374b675b716fe781f6aa1e93cb477af32d Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 13 Nov 2025 10:13:16 -0600 Subject: [PATCH 2/8] Revert setting empty attributes object in favor of warning within registration --- packages/blocks/src/api/registration.js | 17 +++++++++++++++++ packages/blocks/src/store/process-block-type.js | 8 -------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 42fba15241200a..7cac6ff2773014 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -257,6 +257,23 @@ export function registerBlockType( blockNameOrMetadata, settings ) { return; } + // Warn if attributes is explicitly set to undefined or null in metadata or settings. + if ( + ( isObject( blockNameOrMetadata ) && + 'attributes' in blockNameOrMetadata && + ( blockNameOrMetadata.attributes === null || + blockNameOrMetadata.attributes === undefined ) ) || + ( 'attributes' in settings && + ( settings.attributes === null || + settings.attributes === undefined ) ) + ) { + warning( + 'The block "' + + name + + '" must not register attributes as null or undefined. Use an empty object or exclude the attributes key.' + ); + } + const { addBootstrappedBlockType, addUnprocessedBlockType } = unlock( dispatch( blocksStore ) ); diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 7249c0072716e5..04259be4d33d56 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -103,14 +103,6 @@ export const processBlockType = ), }; - // Ensure attributes is always an object, never null or undefined. - if ( - ! blockType.attributes || - typeof blockType.attributes !== 'object' - ) { - blockType.attributes = {}; - } - const settings = applyFilters( 'blocks.registerBlockType', blockType, From 1c1fee6cda0bbe688db33b9c2d789a64f72b1a67 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 11:40:16 -0600 Subject: [PATCH 3/8] Revert "Revert setting empty attributes object in favor of warning within registration" This reverts commit 43a149374b675b716fe781f6aa1e93cb477af32d. --- packages/blocks/src/api/registration.js | 17 ----------------- packages/blocks/src/store/process-block-type.js | 8 ++++++++ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 7cac6ff2773014..42fba15241200a 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -257,23 +257,6 @@ export function registerBlockType( blockNameOrMetadata, settings ) { return; } - // Warn if attributes is explicitly set to undefined or null in metadata or settings. - if ( - ( isObject( blockNameOrMetadata ) && - 'attributes' in blockNameOrMetadata && - ( blockNameOrMetadata.attributes === null || - blockNameOrMetadata.attributes === undefined ) ) || - ( 'attributes' in settings && - ( settings.attributes === null || - settings.attributes === undefined ) ) - ) { - warning( - 'The block "' + - name + - '" must not register attributes as null or undefined. Use an empty object or exclude the attributes key.' - ); - } - const { addBootstrappedBlockType, addUnprocessedBlockType } = unlock( dispatch( blocksStore ) ); diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 04259be4d33d56..7249c0072716e5 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -103,6 +103,14 @@ export const processBlockType = ), }; + // Ensure attributes is always an object, never null or undefined. + if ( + ! blockType.attributes || + typeof blockType.attributes !== 'object' + ) { + blockType.attributes = {}; + } + const settings = applyFilters( 'blocks.registerBlockType', blockType, From e67d081e9e3227ea35269df318155b9066f9b3ae Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 11:44:28 -0600 Subject: [PATCH 4/8] Add warning when passing attributes as undefined and inform that this is a temporary fix in gutenberg --- packages/blocks/src/store/process-block-type.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 7249c0072716e5..43e20b3fcacd57 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -103,11 +103,16 @@ export const processBlockType = ), }; - // Ensure attributes is always an object, never null or undefined. + // Temporary fix to allow block authors time to fix blocks that register attributes as null or undefined. if ( ! blockType.attributes || typeof blockType.attributes !== 'object' ) { + warning( + 'The block "' + + name + + '" must not register attributes as null or undefined. Use an empty object (`attributes: {}`) or exclude the attributes key. In the next Gutenberg release, passing null or undefined for attributes will cause the block editor to crash.' + ); blockType.attributes = {}; } From d7c504142020daba59ae6bd6f4c782cce9d30303 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 11:51:02 -0600 Subject: [PATCH 5/8] Update warning message Co-authored-by: Marin Atanasov <8436925+tyxla@users.noreply.github.com> --- packages/blocks/src/store/process-block-type.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index 43e20b3fcacd57..f032a4b52921ed 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -111,7 +111,7 @@ export const processBlockType = warning( 'The block "' + name + - '" must not register attributes as null or undefined. Use an empty object (`attributes: {}`) or exclude the attributes key. In the next Gutenberg release, passing null or undefined for attributes will cause the block editor to crash.' + '" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' ); blockType.attributes = {}; } From 2a0657331ea04b8847dfbd01076aa939d258c9b0 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 12:04:44 -0600 Subject: [PATCH 6/8] Add unit tests for block registration with undefined, null, or no attributes key --- packages/blocks/src/api/test/registration.js | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index b61845203844a2..b042904a672881 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -304,6 +304,56 @@ describe( 'blocks', () => { } ); } ); + it( 'should default to empty object when attributes is omitted and without warning', () => { + registerBlockType( 'core/test-block-omitted-attributes', { + title: 'block title', + category: 'text', + save: noop, + } ); + + // Verify no warning was shown (unlike when explicitly set to null/undefined) + expect( console ).not.toHaveWarned(); + + const blockType = getBlockType( + 'core/test-block-omitted-attributes' + ); + expect( blockType.attributes ).toEqual( {} ); + } ); + + it( 'should warn and default to empty object when attributes is undefined', () => { + registerBlockType( 'core/test-block-undefined-attributes', { + title: 'block title', + category: 'text', + save: noop, + attributes: undefined, + } ); + + expect( console ).toHaveWarnedWith( + 'The block "core/test-block-undefined-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' + ); + + const blockType = getBlockType( + 'core/test-block-undefined-attributes' + ); + expect( blockType.attributes ).toEqual( {} ); + } ); + + it( 'should warn and default to empty object when attributes is null', () => { + registerBlockType( 'core/test-block-null-attributes', { + title: 'block title', + category: 'text', + save: noop, + attributes: null, + } ); + + expect( console ).toHaveWarnedWith( + 'The block "core/test-block-null-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' + ); + + const blockType = getBlockType( 'core/test-block-null-attributes' ); + expect( blockType.attributes ).toEqual( {} ); + } ); + it( 'should default to browser-initialized global attributes', () => { const attributes = { ok: { type: 'boolean' } }; unstable__bootstrapServerSideBlockDefinitions( { From 99c3dbb00243a290691a2c6db67989e8ecc06380 Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 13:01:44 -0600 Subject: [PATCH 7/8] Use it to avoid duplication in unit test Co-authored-by: Marin Atanasov <8436925+tyxla@users.noreply.github.com> --- packages/blocks/src/api/test/registration.js | 52 ++++++++------------ 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index b042904a672881..deb4ca7ea24bfd 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -320,39 +320,29 @@ describe( 'blocks', () => { expect( blockType.attributes ).toEqual( {} ); } ); - it( 'should warn and default to empty object when attributes is undefined', () => { - registerBlockType( 'core/test-block-undefined-attributes', { - title: 'block title', - category: 'text', - save: noop, - attributes: undefined, - } ); - - expect( console ).toHaveWarnedWith( - 'The block "core/test-block-undefined-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' - ); - - const blockType = getBlockType( - 'core/test-block-undefined-attributes' - ); - expect( blockType.attributes ).toEqual( {} ); - } ); - - it( 'should warn and default to empty object when attributes is null', () => { - registerBlockType( 'core/test-block-null-attributes', { - title: 'block title', - category: 'text', - save: noop, - attributes: null, - } ); + it.each( [ + [ 'undefined', undefined ], + [ 'null', null ], + ] )( + 'should warn and default to empty object when attributes is %s', + ( _label, value ) => { + registerBlockType( 'core/test-block-null-attributes', { + title: 'block title', + category: 'text', + save: noop, + attributes: value, + } ); - expect( console ).toHaveWarnedWith( - 'The block "core/test-block-null-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' - ); + expect( console ).toHaveWarnedWith( + 'The block "core/test-block-null-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' + ); - const blockType = getBlockType( 'core/test-block-null-attributes' ); - expect( blockType.attributes ).toEqual( {} ); - } ); + const blockType = getBlockType( + 'core/test-block-null-attributes' + ); + expect( blockType.attributes ).toEqual( {} ); + } + ); it( 'should default to browser-initialized global attributes', () => { const attributes = { ok: { type: 'boolean' } }; From ac103818b44a80d93ca8dd3e2880f5b96337f37e Mon Sep 17 00:00:00 2001 From: Jerry Jones Date: Thu, 20 Nov 2025 13:07:02 -0600 Subject: [PATCH 8/8] Remove temporary messaging about the fix being removed --- packages/blocks/src/api/test/registration.js | 2 +- packages/blocks/src/store/process-block-type.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index deb4ca7ea24bfd..5a37017be46636 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -334,7 +334,7 @@ describe( 'blocks', () => { } ); expect( console ).toHaveWarnedWith( - 'The block "core/test-block-null-attributes" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' + 'The block "core/test-block-null-attributes" is registering attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key.' ); const blockType = getBlockType( diff --git a/packages/blocks/src/store/process-block-type.js b/packages/blocks/src/store/process-block-type.js index f032a4b52921ed..3da02e69ae5263 100644 --- a/packages/blocks/src/store/process-block-type.js +++ b/packages/blocks/src/store/process-block-type.js @@ -103,7 +103,7 @@ export const processBlockType = ), }; - // Temporary fix to allow block authors time to fix blocks that register attributes as null or undefined. + // If the block is registering attributes as null or undefined, warn and default to empty object. if ( ! blockType.attributes || typeof blockType.attributes !== 'object' @@ -111,7 +111,7 @@ export const processBlockType = warning( 'The block "' + name + - '" must not register attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key. In the next Gutenberg release, passing `null` or `undefined` for `attributes` will cause the block editor to crash.' + '" is registering attributes as `null` or `undefined`. Use an empty object (`attributes: {}`) or exclude the `attributes` key.' ); blockType.attributes = {}; }