AdvancedCustomFields / AdvancedCustomFields/acf
Drop trap, acf_after_title
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 945
- Forks
- 197
- PR merge metrics
- No merged PRs in 30d
Description
Describe the bug
ACF renders a hidden, empty #acf_after_title-sortables meta box container on every block editor post screen, even when no field group uses the acf_after_title position. Because WordPress' postboxes.js connects all .meta-box-sortables elements as jQuery UI sortable drop targets, users can drag non ACF meta boxes into this invisible container. The drop is persisted by postboxes.save_order() into the user's meta-box-order_{$screen} user meta under an acf_after_title bucket.
On the next load, WP core re-registers those box IDs into the acf_after_title context via add_meta_box( $id, null, null, $screen, $box_context, 'sorted' ) (wp-admin/includes/template.php:1324–1332). Gutenberg only renders side/normal/advanced visibly, so the box disappears for that user, the corruption is per-user, not site wide, and is permanent because ACF's existing self repair never runs in this scenario.
To Reproduce
- Install ACF 6.8.9 with no field group set to the "High (after title)" position.
- Open any post in the block editor with at least one classic meta box present (e.g. a plugin meta box).
- Inspect the hidden
.metabox-base-formform rendered bythe_block_editor_meta_boxes(), it contains an empty<div id="acf_after_title-sortables" class="meta-box-sortables"></div>output byACF_Form_Post::edit_form_after_title()→do_meta_boxes( get_current_screen(), 'acf_after_title', $post )(includes/forms/form-post.php:206). - Start dragging a meta box in the editor.
assets/build/css/acf-input.css(body.is-dragging-metaboxes #acf_after_title-sortables { outline: 3px dashed; min-height: 60px; }) paints the invisible container as a visible drop target (assets/src/sass/_postbox.scss:63). - Drop the box into the
acf_after_titledrop zone. - Reload the editor. The dropped box no longer appears anywhere on the screen, and
get_user_option( 'meta-box-order_{$screen}' )now contains anacf_after_titlebucket with the box ID.
Expected behavior
With no field groups registered at the acf_after_title position, the hidden form should contain no #acf_after_title-sortables container, so there is no droppable target and no way to corrupt the user's meta box order. Field groups actually positioned acf_after_title must continue to render, sort, and save as before, and the hidden acf_form_data() inputs (nonce/screen/post_id) must still render on every post edit screen.
Screenshots or Video
N/A
Code
No field group or block code is involved, the bug reproduces with zero ACF field groups at the acf_after_title position and any other plugin registered meta box.
Version Information:
- WordPress Version 6.9.x and later
- PHP Version 8.2
- ACF Version 6.8.9
- Browser Chrome, Safari, Firefox
Additional context
Why the existing repair never fires, WP core's the_block_editor_meta_boxes() (wp-admin/includes/post.php):
- Applies
filter_block_editor_meta_boxes(~line 2375), at this point theacf_after_titlebucket only contains boxes registered at that position (i.e. ACF field groups with positionacf_after_title). With none present,ACF_Form_Gutenberg::filter_block_editor_meta_boxes()never attaches itsmodify_user_option_meta_box_orderrepair filter (includes/forms/form-gutenberg.php:107–149). - ACF's hidden-fields render (
block_editor_meta_box_hidden_fields→ACF_Form_Post::edit_form_after_title()) is where the firstdo_meta_boxes()call happens core re-registers box IDs found underacf_after_titlein the user's saved order. - Only
side/normal/advancedrender visibly afterwards, then the box is gone.
Root causes:
includes/forms/form-post.php,ACF_Form_Post::add_meta_boxes()unconditionally addsadd_action( 'edit_form_after_title', ... )(~line 171), andedit_form_after_title()callsdo_meta_boxes( ..., 'acf_after_title', ... )with no guard for whether anything exists in that context.do_meta_boxes()always outputs the<div id="{context}-sortables" class="meta-box-sortables">wrapper, even when empty.includes/forms/form-gutenberg.php,block_editor_meta_box_hidden_fields()re-runs the same unguarded render inside the hidden form.
Suggested fix (render gating): in ACF_Form_Post::edit_form_after_title(), guard the do_meta_boxes( ..., 'acf_after_title', ... ) call on isset( $wp_meta_boxes[ get_current_screen()->id ]['acf_after_title'] ), keeping acf_form_data() unconditional. This removes the empty drop target while preserving rendering when the context genuinely has content, and works for both the classic and block editors since both paths call the same method.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in includes/forms/form-post.php, reading ACF_Form_Post::add_meta_boxes() and edit_form_after_title(), then compare the hidden-form path in includes/forms/form-gutenberg.php. Verify that acf_form_data() remains unconditional, that the acf_after_title container is omitted when its context is empty, and that field groups using that position still render and sort.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100