The Problem
A client ran the routine WordPress 6.9 update on a block theme site Monday morning, opened the Site Editor to tweak the header template, hit Save, and got the green confirmation. Refreshed the front end and the change was not there. Opened the editor again and the change was still in the canvas, but the template now showed a small Draft badge next to the name. Every save was being committed as a private revision instead of overwriting the live template part.
The frustrating part: nothing in the editor told them this was happening. The save toast read "Site updated" exactly like it always had. The only signal was a tiny badge buried in the template browser, and the front end quietly serving the old markup. Two editors on the team spent an hour assuming a cache plugin was eating the changes before anyone noticed the badge.
This started the day they upgraded from 6.8 to 6.9 on a multisite where their primary editors had the Editor role, not Administrator. Admins could save and publish in one click. Editors got drafts they could not promote.
Why It Happens
WordPress 6.9 introduced a new template autosave model and tightened the capability check on user-edited template parts that live in the database (the wp_template_part post type). The intention was sensible: stop accidental overwrites of header and footer templates when several people are in the editor at once. The implementation hooked the existing edit_theme_options capability check to a second, narrower check on edit_published_template_parts, which is a meta capability that maps differently per role.
Administrators get this capability mapped to true by default. Editors and any custom role built on the Editor base do not. When a non-admin saves a template part that has already been published once, the REST endpoint returns a 200 with the saved post id, but the post is created as a revision in post_status = 'draft' and the live publish row is left alone. The editor UI reads the response as success, the autosave indicator clears, and the front end keeps rendering the stale version.
You will not see a PHP warning. You will not see a deprecation notice. The REST log shows a clean POST /wp-json/wp/v2/template-parts/<id>/autosaves returning 201 and another save call returning 200. Both are technically correct. The capability quietly downgraded the publish to a draft and nobody told the editor.
The WordPress 6.9 release post mentions the capability split in passing, but unless you run a multi-author block theme site you would not look twice at it.
The Fix
Two options depending on how strict you want the workflow to be. The right one for most agency-built sites is to restore publish rights for the Editor role on template parts.
Option 1: Grant the capability to existing roles. Drop this into the theme's functions.php or a small mu-plugin and run it once on activation:
add_action('init', function () {
$roles = ['editor', 'shop_manager'];
$caps = [
'edit_published_template_parts',
'edit_published_templates',
'publish_template_parts',
'publish_templates',
];
foreach ($roles as $role_name) {
$role = get_role($role_name);
if (! $role) {
continue;
}
foreach ($caps as $cap) {
if (! $role->has_cap($cap)) {
$role->add_cap($cap);
}
}
}
});
The init hook is intentional: capability changes persist in wp_options, so you only need this to fire on plugin activation or after a role reset. Running it on every request is harmless but wasteful, so for a long-lived site move the loop into a one-shot migration:
register_activation_hook(__FILE__, function () {
$role = get_role('editor');
if (! $role) {
return;
}
$role->add_cap('edit_published_template_parts');
$role->add_cap('edit_published_templates');
$role->add_cap('publish_template_parts');
$role->add_cap('publish_templates');
});
After that runs, log out and back in as the Editor account (capability checks read from the session) and try saving a template part again. The Draft badge should not appear and the front end should update.
Option 2: Lock the workflow down deliberately. If the reason the cap got tightened is exactly what you want (juniors edit, senior reviews and publishes), surface the draft state in the UI so saves are not silent. Add a small editor sidebar notice via a custom block plugin that reads the template part post status and shows a warning when it is draft:
import { registerPlugin } from '@wordpress/plugins'
import { PluginPostStatusInfo } from '@wordpress/edit-site'
import { useSelect } from '@wordpress/data'
const TemplateDraftWarning = () => {
const status = useSelect(
(s) => s('core/editor').getEditedPostAttribute('status'),
[],
)
if (status !== 'draft') return null
return (
<PluginPostStatusInfo>
<p style={{ color: '#b32d2e' }}>
This template is a draft. Ask an admin to publish.
</p>
</PluginPostStatusInfo>
)
}
registerPlugin('template-draft-warning', { render: TemplateDraftWarning })
The editors at least see they are working on a draft and can ping the admin to promote it. The default UI offers no such hint, which is half of why this bug is painful in the first place.
Verify before handing the site back. Promote a known editor account, save a template change, then run this in the database:
SELECT ID, post_title, post_status, post_modified
FROM wp_posts
WHERE post_type = 'wp_template_part'
ORDER BY post_modified DESC
LIMIT 5;
You should see one row in publish and any older edits in draft or auto-draft. If every recent save is still landing in draft, the capability change has not taken effect for that session yet. Log the user out and back in.
The Lesson
WordPress 6.9 quietly split the publish capability for template parts and the Site Editor returns a clean "saved" response either way. Editor-role accounts on block theme sites silently create draft revisions and admins keep wondering why the header never updates. Grant edit_published_template_parts and publish_template_parts to the roles that need to publish, or surface the draft state in the editor so the silence stops.
If a block theme upgrade has stalled your client's content workflow and you need it untangled without a week of trial-and-error, that is the kind of fix I take on. See my services. For a related block theme regression after a major version bump, read WordPress 6.9 block styles broken layout.
Editors saving drafts they cannot publish? I can fix it.