Repository navigation
Docs: Improve wording and accuracy of block asset registration docblocks in blocks.php - #11851
Closed
deepakrohillas wants to merge 107 commits into
Closed
deepakrohillas wants to merge 107 commits into
deepakrohillas wants to merge 107 commits into
Conversation
… add_action() `error.message` LIKE 'Uncaught exception 'Error' with message 'Call to undefined function add_action()' in /var/www/wp-content/plugins/hello.php:69%' AND `error.class` = 'Error' AND transactionUiName = '/wp-content/plugins/hello.php' 'request_uri': '/wp-content/plugins/hello.php'
…dolly_uncaught_exception Fix Uncaught exception Error with message 'Call to undefined function…
…PATH direct access to wp-includes/rss.php on line 19 https://core.trac.wordpress.org/ticket/61277
Plugin URI http to https change
t-hamano
approved these changes
Aug 1, 2026
Relax the metadata version key from non-falsy-string to non-empty-string, since a block.json version of "0" is legal and would be a falsy string. The value only ever flows to a $ver parameter that accepts any string. Add the non-falsy-string|false return to register_block_style_handle(), which the other two registration functions already carry. Every return path is false, a handle taken from the metadata, or one generated by generate_block_asset_handle(), so PHPStan verifies it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The narrowed non-falsy-string was added as a second plain return tag, leaving the function with two of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
Member
|
Note: Ignore the changes I've made outside of |
…id() The block.json schema does not set `additionalProperties: false` on the `supports.interactivity` object, so a block may legitimately declare keys beyond `interactive` and `clientNavigation`. Sealing the shape asserted otherwise. This matches `supports` itself, which the schema explicitly marks as `additionalProperties: true` and which was already unsealed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…deepakrohillas/plugin_hello_dolly_uncaught-exception_error into typo_wp_includes_blocks_dot_php
…core blocks The description had the two cases inverted. When wp_should_load_separate_core_block_assets() returns true, the style is registered from the block's own stylesheet, resolved from the block directory as dirname( $metadata['file'] ) . '/style.min.css'. The single combined 'wp-block-library' stylesheet is what serves core block styles in the opposite case, where the function returns false and registers nothing. This matches wp_should_load_separate_core_block_assets() itself, which documents that a true return makes core blocks use their own separate stylesheets, as well as the inline comment contrasting individual styles with the bundled version. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `file` key is not a block.json field but is injected by
register_block_type_from_metadata(), which assigns null whenever the block
has no metadata file:
$metadata['file'] = $metadata_file_exists ? wp_normalize_path( realpath( $metadata_file ) ) : null;
That branch is reachable from an ordinary call, because the guard above it
accepts a name supplied through `$args` when the metadata itself has none.
Registering a folder without a block.json then reaches dirname( null ) in all
three functions, which is deprecated as of PHP 8.1:
Deprecated: dirname(): Passing null to parameter #1 ($path) of type string
is deprecated in blocks.php on line 187
The functions were already inconsistent about this: register_block_style_handle()
guards the key with isset(), then dereferences it unguarded 23 lines later.
Declaring the key nullable surfaces the three dirname() call sites rather than
asserting they cannot happen. Fixing them is left for a separate change, since
the same call path also leaves `name` undefined.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…hapes
The guard in register_block_type_from_metadata() only requires that one of
the two possible sources supplies a name:
if ( ! is_array( $metadata ) || ( empty( $metadata['name'] ) && empty( $args['name'] ) ) ) {
So a block named through `$args` alone gets past it with no name in the
metadata itself. The two are reconciled, but not until after the three asset
functions have already run:
$metadata['name'] = ! empty( $settings['name'] ) ? $settings['name'] : $metadata['name'];
The asset loops copy `$args`-supplied values into `$metadata` for the asset
fields only, never for the name, so all three functions can be reached with
the key absent:
Warning: Undefined array key "name" in blocks.php on line 189
The consequence is not only a warning. generate_block_asset_handle() then
produces '-script', '-style' and '-view-script-module', which every nameless
block shares, so the second such block matches the wp_script_is() check and
silently adopts the first one's registration.
This describes the behavior as it currently stands. Reordering the
reconciliation would make the key genuinely required, but that changes which
name the generated handles reflect when the block_type_metadata_settings
filter renames a block, so it is left for a separate change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The block.json schema constrains only `name`, whose pattern
`^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$` rules out a falsy value. The seven asset
fields are `oneOf` a string or an array of strings, and `version` and
`textdomain` are plain strings, none of them carrying a pattern or a
minLength. Declaring them as non-falsy claimed a guarantee the schema does
not make.
An empty value is also not hypothetical. Published plugins ship it at the top
level of block.json, for example:
"textdomain": "omnisend-checkout-block",
"editorStyle": ""
Core ignores those silently, since register_block_type_from_metadata() only
calls the three functions when the field passes ! empty(). The narrowing was
therefore load-bearing for nothing: the empty() guards that open each
function already establish the non-falsy return type, so relaxing these
eleven declarations leaves the error count unchanged at 282.
`name` keeps its non-falsy-string, both because the schema pattern
establishes it and because generate_block_asset_handle() requires it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Core defines the constant as `__DIR__ . '/'` everywhere it appears, and the
separator is load-bearing rather than incidental. The comment core attaches
to the very next constant makes that explicit:
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // No trailing slash, full paths only
Without it the bootstrap produced `…/srcwp-content`, and the error carried
into WP_PLUGIN_DIR, WPMU_PLUGIN_DIR, TEMPLATEPATH, STYLESHEETPATH and
BLOGUPLOADDIR, as well as into every `ABSPATH . WPINC` in the analysed code.
Nothing is reported differently as a result, since PHPStan does not resolve
these paths on disk: the five files that exercise them report 1351 errors
either way. The value was simply wrong.
Also give the WP_Filesystem() reference its parentheses, matching the other
`@see` tags in the file and distinguishing the function from a class that
does not exist.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deriving the constant from __DIR__ gave it the developer's own checkout
location, which PHPStan then folded into the text of any error mentioning a
path built from it:
Binary operation "." between '/Users/westonruter…' and mixed results in an error.
Three messages across the analysed files carried that prefix, so output was
not reproducible between machines and a generated baseline would not have
been portable.
Nothing resolves files through the constant, so a fixed path serves the same
purpose. The same three messages now read '/var/www/html/wp…' and the error
count is unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…strap These were the last placeholders left over from the surrounding constants being made realistic. All of them now match what core would define: - WP_LANG_DIR follows the first branch of wp_set_lang_dir(), which is the common case. The other branch builds on WPINC, which the bootstrap never defines, so it is not available here. - FS_CONNECT_TIMEOUT and FS_TIMEOUT are 30 seconds in WP_Filesystem(). - FS_CHMOD_DIR and FS_CHMOD_FILE are computed there from fileperms(), which cannot run against a fictional ABSPATH. The literals are the floor those expressions guarantee through `| 0755` and `| 0644`. The values are documentation rather than input to the analysis. WP_LANG_DIR is listed in dynamicConstantNames so PHPStan discards it, and the FS_* constants are integers either way. Across the twenty-two files that reference any of them, the results are byte for byte identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PHPStan reads the value the bootstrap actually produces, so microtime( true )
gave the constant a different literal type on every run:
Dumped type: 1785652449.138539
Dumped type: 1785652451.311018
It is read at functions.php:9014 and class-wp-debug-data.php:2012, both
subtracting it from microtime( true ) to measure elapsed time. A fixed value
serves that just as well and keeps the analysis reproducible, for the same
reason ABSPATH no longer derives from __DIR__.
Both consuming files report 658 errors either way.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pento
pushed a commit
that referenced
this pull request
Aug 2, 2026
Many constants were defined as empty strings, including ones that never hold an empty value in a real install. Realistic values are provided for those, matching what wp-settings.php and default-constants.php would produce, so that functions building on them can be given narrower types without the placeholder itself violating them. Constants core itself defines as empty, such as WP_DEVELOPMENT_MODE and COOKIE_DOMAIN, are left as they were. Developed as subset of #11851. See #64898. git-svn-id: https://develop.svn.wordpress.org/trunk@62965 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith
pushed a commit
to markjaquith/WordPress
that referenced
this pull request
Aug 2, 2026
Many constants were defined as empty strings, including ones that never hold an empty value in a real install. Realistic values are provided for those, matching what wp-settings.php and default-constants.php would produce, so that functions building on them can be given narrower types without the placeholder itself violating them. Constants core itself defines as empty, such as WP_DEVELOPMENT_MODE and COOKIE_DOMAIN, are left as they were. Developed as subset of WordPress/wordpress-develop#11851. See #64898. Built from https://develop.svn.wordpress.org/trunk@62965 git-svn-id: http://core.svn.wordpress.org/trunk@62206 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento
pushed a commit
that referenced
this pull request
Aug 2, 2026
Per the inline documentation standards, a docblock's summary belongs on its own line separated from the description, and the description should not open with "It". This is applied to `register_block_script_module_id()`, `register_block_script_handle()`, and `register_block_style_handle()`, together with some missing articles in the same descriptions. Two of those descriptions no longer matched the code. `register_block_script_handle()` said the script is registered under an automatically generated handle, but since 6.5.0 the handle is taken from the asset file whenever one provides it, and generation is only the fallback. `register_block_style_handle()` said it returns the unprocessed style handle otherwise, which does not hold for the first style of a core block: that one is registered from the block's own stylesheet when separate core block assets are loaded, and skipped entirely when they are not. The same functions gain `@phpstan-` annotations describing the shape of the `$metadata` they accept and the narrower strings they return. The shapes follow the `block.json` schema, which constrains only `name`, so the remaining fields stay plain strings; `file` is nullable and `name` optional because `register_block_type_from_metadata()` can reach all three functions with neither present. Developed in #11851. Follow-up to r48141, r55447, r57559, r57565. Props deepakrohilla, westonruter, sabernhardt, wildworks, audrasjb. See #64898. Fixes #65259. git-svn-id: https://develop.svn.wordpress.org/trunk@62966 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith
pushed a commit
to markjaquith/WordPress
that referenced
this pull request
Aug 2, 2026
Per the inline documentation standards, a docblock's summary belongs on its own line separated from the description, and the description should not open with "It". This is applied to `register_block_script_module_id()`, `register_block_script_handle()`, and `register_block_style_handle()`, together with some missing articles in the same descriptions. Two of those descriptions no longer matched the code. `register_block_script_handle()` said the script is registered under an automatically generated handle, but since 6.5.0 the handle is taken from the asset file whenever one provides it, and generation is only the fallback. `register_block_style_handle()` said it returns the unprocessed style handle otherwise, which does not hold for the first style of a core block: that one is registered from the block's own stylesheet when separate core block assets are loaded, and skipped entirely when they are not. The same functions gain `@phpstan-` annotations describing the shape of the `$metadata` they accept and the narrower strings they return. The shapes follow the `block.json` schema, which constrains only `name`, so the remaining fields stay plain strings; `file` is nullable and `name` optional because `register_block_type_from_metadata()` can reach all three functions with neither present. Developed in WordPress/wordpress-develop#11851. Follow-up to r48141, r55447, r57559, r57565. Props deepakrohilla, westonruter, sabernhardt, wildworks, audrasjb. See #64898. Fixes #65259. Built from https://develop.svn.wordpress.org/trunk@62966 git-svn-id: http://core.svn.wordpress.org/trunk@62207 1a063a9b-81f0-0310-95a4-ce76da25c4cd
noaholuwaphilip-bot
approved these changes
Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Trac ticket: https://core.trac.wordpress.org/ticket/65259
Reworks the docblocks for the three block asset registration functions in
src/wp-includes/blocks.php, corrects two descriptions that no longer matched the code, and fixes thebefore handtypo inbuild_query_vars_from_query_block()that this ticket was originally filed for.Wording
Per the inline documentation standards, the summary belongs on its own line separated from the description by a blank line, and the description should not open with "It". Applied to
register_block_script_module_id(),register_block_script_handle(), andregister_block_style_handle().Missing articles are added in the same three descriptions: "a path to file" becomes "a path to a file", and "returns unprocessed x handle" becomes "returns the unprocessed x handle".
Accuracy
Two of the descriptions no longer described what the functions do:
register_block_script_handle()said the script is registered "under an automatically generated handle name". Since 6.5.0 the handle is taken from the asset file when it provides one —$script_asset['handle'] ?? generate_block_asset_handle( … )— which the function's own@since 6.5.0line already documents. Automatic generation is now described as the fallback it is.register_block_style_handle()said it "returns unprocessed style handle otherwise". That does not hold for the first style of a core block, which is registered from the bundledstyle.min.css/editor.min.csseven when a plain handle was given. Core blocks also returnfalseoutright when given a path rather than a handle.register_block_script_module_id()was checked against its implementation and needed no accuracy change — it always generates the module ID.Typo
In
build_query_vars_from_query_block(), "before hand" becomes "beforehand".🤖 This PR title and description were rewritten by Claude Code (Claude Opus 5) to reflect the changes as they now stand. The original is preserved below.
Original title and description
Title:
Docs: Fix inline comment typos in build_query_vars_from_query_block() in blocks.php