You typed two fields into the order. WooCommerce kept one
Since 4 August the order items form throws away any meta key an extension has registered as hidden. The row vanishes on save, the screen reports success, and nothing is written to the log. WooCommerce's own documentation still tells store owners to type one of those keys.
One key saved, the other did not
The order editor has a small button under each line item called Add meta. You click it, a blank name and value appear, you type a key, you type a value, you save. It has worked that way for years, and extension documentation sends people there routinely.
In August a store owner followed exactly such a set of instructions on a live membership site - 4,675 subscriptions, 3,225 teams - and reported what happened:
team_namesaves successfully._wc_memberships_for_teams_team_idis silently discarded. No error or notice is shown, and because the key is registered inwoocommerce_hidden_order_itemmetathe admin gives no indication anything is missing.
- the reporter, WooCommerce issue #67440, 6 August 2026
Two fields, typed into the same panel and stored by the same click on Save. One landed. One did not. The order screen afterwards looks the same either way, because the missing key is a hidden one - it never renders in that panel even when it is there.
Four lines, added twice
WooCommerce 11.0.0, released 4 August 2026, added a guard to the function that saves order items from the admin. In the 11.0.0 source it reads:
// Skip reserved keys, which cannot be added or edited as custom meta.
if ( in_array( $meta_key, $reserved_meta_keys, true ) ) {
continue;
}That is the whole change. Compare the same file at
10.9.0
and the difference is one use statement, one line that builds the reserved list
for the item, and those four lines - the last two inserted twice, once in the loop
that handles line items and fees, once in the loop for shipping lines.
continue and nothing else. No logger call, no admin notice, no order note, no
change to what the save routine returns. The vendor describes the effect for
extensions in its own words:
If your extension registers keys in
woocommerce_hidden_order_itemmetathose will be skipped not just for rendering, as usual, but now also at save time, failing silently.
- Reserved item meta keys are no longer persisted in the admin, WooCommerce Developer Blog, 18 August 2026, read 8 September 2026
The browser side does not help either. The Add meta button is a few lines of jQuery that append a blank text input to the row; it holds no list of forbidden names and shows no warning. So the form accepts the key, posts it, and the server drops it.
Which keys are reserved? Not the ones you would guess
The intuitive rule - "internal things start with an underscore" - is wrong in both directions, and getting it wrong is not a beginner's mistake. When the issue above was escalated, one WooCommerce engineer read the change that way and the author of the change corrected him:
It's neither of the two. There's no rule based on the
_prefix: when saving order items we skip keys that are either internal to the data store (_product_id,_qty, etc.) or registered as hidden via thewoocommerce_hidden_order_itemmetafilter. Teams is affected because it registers_wc_memberships_for_teams_team_idin that filter, but in general keys not registered as hidden still save fine, underscore or not.
- the WooCommerce engineer who authored the change, issue #67440, 10 August 2026
It took several exchanges between two Automattic engineers, and a screen recording, to settle what the change does - a fair measure of how slippery the distinction is. Practically:
_my_own_keysaves normally. The underscore is irrelevant. WooCommerce says so directly: order item meta "doesn't follow rules similar to WordPress protected meta".cost,taxes,instance_id,total_taxandmethod_idare reserved on a shipping line, with no underscore anywhere. They are the shipping item's own data-store fields.- Anything an active extension has registered as hidden is reserved, whatever it is called.
That last category is where ordinary English words end up. Reading the source of
plugins in the WordPress.org directory, the filter is currently carrying names like
type, provider_name, carrier_code and instance_id (Montonio for
WooCommerce), and Original Price and Selected Template (Ultimate Gift Cards for
WooCommerce - two keys with a space in them). If one of those plugins is active on
your shop and you type type or Original Price into Add meta for a reason of
your own, the value goes nowhere.
Read from plugin sources rather than observed on a live shop. The list of reserved keys on your store depends on which extensions are active, so the authority on your shop is your shop.
The published lists are not the full list
There is a further wrinkle worth knowing if you are debugging this rather than just avoiding it. WooCommerce builds the reserved list from two places: the filter, and the item data store's internal keys. That second list is not static - while an item is being read, the data store adds underscore-prefixed copies of the item's own data fields to it.
Following that through the 11.0.0 source, a product line item ends up with 21
reserved keys rather than the 13 the two published lists describe, and the extra
ones are _name, _total, _quantity, _subtotal, _taxes and their
neighbours. Those are exactly the names somebody would reach for when stashing a
value on a line item, and none of them appear in the advisory, in the filter's
default list, or in any data store's declared keys.
This one is read from the source and has not been run, so treat it as a thing to check rather than a fact about your shop - the last step of the test below is how to settle it, on a staging copy.
How many extensions does this touch?
More than the advisory's single named example suggests. Searching the source of
every plugin in the WordPress.org directory for registrations of that filter
returns 271 matches across 245 plugins (searched 8 September 2026). Among them,
by the directory's own install counts in early September: WooPayments at 800,000
installs, which bundles the Subscriptions core that hides _has_trial; WooCommerce
Tax at 500,000, hiding wc_connect_packages; WPML's WooCommerce integration at
100,000; WooCommerce Square at 80,000; Germanized at 70,000, which hides thirty-odd
keys across two registrations.
One plugin, Booster for WooCommerce, registers 400 of them in a loop. Several of
the largest on that list are WooCommerce's own plugins, so on a fairly ordinary
shop, part of the list of names the form will now refuse comes from the vendor
itself.
Two things that number is not. It is not a count of broken stores - registering a hidden key breaks nothing by itself, and most of those keys are written by code that never touches this form. And it says nothing about paid extensions, which are not in that directory at all and which are the ones whose documentation is most likely to ask an admin to type a key by hand.
What the number does describe is the size of the surface: on a shop with a dozen extensions, the set of key names the order form will silently refuse is not something anybody has written down.
WooCommerce still documents the thing it broke
The clearest case of this failing is not hypothetical, and it is not a third party's fault. Teams for WooCommerce Memberships is a Woo Marketplace extension, and its documentation is on woocommerce.com. Under "Link the team to the subscription", it says:
Click Add Meta.
Enter
_wc_memberships_for_teams_team_idas the meta key Name and the team ID (copied to your clipboard!) as the Value.Click Add Meta.
Enter
team_nameas the meta key Name and the team name as the Value.Click Save.
- Teams for WooCommerce Memberships, woocommerce.com, read 8 September 2026
That is the procedure from the report at the top of this article: the first key is registered hidden by the extension, so since 11.0.0 it is discarded; the second one is not, so it saves. Following the documentation to the letter produces a half-finished record and a success message, and the team is never linked to the subscription.
The page carried a last-modified date of 14 January 2026 when it was read on 8 September - unchanged through the release, through the report, and through the month after it. That date lives in the page's metadata rather than on the page, so the practical check if you are reading this later is simply whether the procedure still reads as it does above. It may have been rewritten by now, and it should have been.
The gap is not that nobody updated the documentation. WooCommerce did revise it for this change, just not that page. The general guide to the order screen was updated on 8 August - four days after the release, ten days before the advisory - and now describes the button like this:
Add Meta: Add or remove custom metadata for a line item. WooCommerce ignores reserved fields that it manages internally, so use the standard order-item controls to change product, quantity, total, or tax data.
- Single Order Page and Manually Adding an Order, woocommerce.com, carrying a last-modified date of 8 August 2026, read 8 September 2026
An archived copy of the same page from 19 May 2026 shows what that line used to say, in full: "Add Meta: Add and remove meta to change product variable options." So the general description of the button was rewritten at some point after the middle of May, and the page's most recent edit landed four days after the release. The step-by-step procedure that tells an admin to type a key which is now discarded was not part of that pass.
The report itself was closed on 19 August as not planned, the day after the advisory went up:
As discussed above, this is how it's meant to work. [We've published a dev note] that explains the change and includes workarounds for developers and store owners.
The snippet above should keep the Teams procedure working in the meantime, but I'd also report this to the extension's support so they can update the docs or add a proper UI for it. Showing a notice when a key is rejected is a good idea and we might add something like that in a future version.
- the same WooCommerce engineer, issue #67440, 19 August 2026
Which is a defensible engineering position and leaves a shop owner following official instructions with no way to tell that they did not work.
The change also removed the only warning there was
Here is the part that inverts the usual story about a fix. Before 11.0, typing a
reserved key was loud in one specific case. Keys with a matching setter -
_product_id, _variation_id, _tax_class - went through WooCommerce's
internal-meta check, which calls wc_doing_it_wrong() and therefore wrote a line
into the debug log naming the key:
is_internal_meta_key was called incorrectly. Generic add/update/get meta methods should not be used for internal meta data, including "_variation_id". Use getters and setters.[...]
- the log line, without its backtrace, as quoted in WooCommerce issue #62328 by a user, 8 December 2025
That warning is gone. The new continue sits before the code that produced it, so
the key is skipped without reaching any of it. Nothing about the old behaviour was
good - the same report describes a frozen order screen for some keys and invisible,
unremovable database rows for others - but for anyone with debug logging on, the
old failure at least left a trace with the key name in it. The new one leaves
nothing anywhere.
The person who filed that original report asked for both halves:
I would expect that if these meta items cannot be added via the 'Add meta' button in the order UI, they shouldn't be added at all. They also should not generate any warnings in logs, but perhaps instead showing a helpful message in the UI.
- same issue, 8 December 2025
The first half shipped in 11.0. The second half has not: the guard was still a bare
continue in 11.1.0, the release current on 8 September 2026. If a later version
has added the notice, the changelog entry for it is the thing to look for.
Fourteen days, one changelog line
The change reached shops on 4 August. The advisory explaining it was published on
18 August, fourteen days later. In between, the only public description of it was
one line in the changelog - entry 87 of the 275 in the 11.0.0 block, tagged Fix:
Fix - Order editing: skip reserved internal meta keys when saving order items, so they cannot be added via the "Add meta" button and stored as invisible meta.
readme.txtat tag 11.0.0, woocommerce/woocommerce, read 8 September 2026
Neither the pre-release post for 11.0 nor the release announcement mentions it at all. This is the same shape as the admin menus that came back in 11.1: the explanation exists, on a developer blog, addressed to developers, and the change happens on a shop whose owner was never in that audience. The same release also changed what a failed order does to your stock, which is the louder half of 11.0 and worth reading alongside this if you updated in August.
How do you tell whether this hit you?
Five steps, most of them a few minutes, and they answer the question for your shop rather than for shops in general. Check under WooCommerce then Status which version you are on before starting: everything below assumes 11.0.0 or newer, and on an older version typing an internal key into that form does damage instead of nothing.
- Establish that the form works at all. Open an order whose status is
Pending payment or On hold - line items cannot be edited in any other
status, so on a completed or processing order the pencil icon and the Add meta
button are not drawn at all. Expand a line item, click Add meta, and enter a name
nothing could have reserved -
shop_test_notewill do - with any value. Save, reload. It should be sitting there. If the row is gone, your problem is permissions or a plugin conflict, not this change. - Now enter the key your extension's documentation told you to type, on an order in one of those two statuses. Save, reload, and then ignore that panel, because a hidden key does not render there whether it saved or not. Judge by the feature instead: did the thing the value is supposed to switch on actually switch on? In the Teams case that was visible with no database access at all - the team link simply never appeared on the subscription.
- If you have database access, this is where the exact answer is. Look in
{prefix}woocommerce_order_itemmeta, searching bymeta_keyrather than by item id, and compare the row'smeta_valuewith what you typed. A row that was already there before your edit means the extension wrote it programmatically, which is a different answer from the form having saved it. - Read your extension's documentation for the phrase "Add meta". Any procedure that asks you to type a key name by hand is a candidate, and the ones to check first are membership, subscription, bundle, deposit and point-of-sale plugins.
- On a staging copy only, if you want to map the boundary for your shop, try
names like
_nameor_totalon a line item and check the database for them. That is the claim from earlier in this article that has not been run, and this is how to settle it. Keep it off the live shop anyway: the claim is untested, and if the shop turns out to be on an older version than you thought, that same input renames the line item or overwrites its total instead of being ignored.
If a value you typed does not stick, WooCommerce's advice is to assume the key is hidden rather than to assume the form is broken:
If an extension's documentation asks you to enter a meta key through Add meta and the value doesn't stick, the extension most likely registers that key as hidden.
- Reserved item meta keys are no longer persisted in the admin, WooCommerce Developer Blog, 18 August 2026
What can you do about it?
Three options, in the order most shops should consider them.
Ask the extension's support first. This is not deference, it is the shortest path: the vendor may already have a proper interface for the value, and if the documented procedure is broken, the vendor is the only one who can fix the documentation. Both workarounds below are things you carry until they do.
Unhide the key. WooCommerce publishes a snippet for store owners that removes one key from the hidden list, which makes it visible and editable in the order editor again:
add_filter(
'woocommerce_hidden_order_itemmeta',
fn( $keys ) => array_diff( $keys, array( '_your_meta_key' ) ),
9999
);The trade is that the key is now visible everywhere in that panel, including to staff who have no reason to see it, and that it is only a workaround for keys the extension hid - it does nothing for a key that is internal to the data store.
Re-apply the value as it saves. The advisory's developer-facing option hooks
woocommerce_before_save_order_items and writes the submitted value back with
wc_update_order_item_meta(). It keeps the key hidden. Two limits worth knowing
before you commission it: it only makes sense for keys an extension hid, because a
genuinely internal key gets rewritten from the item's own properties when the item
saves, and it is code you are adding to work around a form, which means somebody has
to remember it exists when the extension is updated.
What none of these do is tell you when a key is refused. That was still true in 11.1.0, and it is the thing to design around rather than wait for: if a value being present matters, check for the value, do not trust the save.
Who owns the key?
That question decides everything about this, including whether it is your job.
If the key belongs to your own code - a field your developer added, a value your own snippet writes - then this is a small piece of work with a clear end. Find the registration, decide whether the key should be hand-editable, and either unhide it or build the value a real input. An afternoon at most, and it stays fixed.
If the key belongs to an extension, you cannot fix it. You can only hold the shop together while somebody else does: a workaround now, a note about where it lives, a check later that it can be removed, and in the meantime a way to verify that the records it touches are actually complete. That is a different shape of work, and its size depends on how many orders were saved between the update and the day you noticed - which for a change that shipped in early August and explained itself two weeks later on a developer blog can be a lot of orders.
Both are scoped jobs with a knowable price, which is how we quote this kind of work, and shop repairs after an update are most of what the website side of the business is. The reason to look this month rather than next is that nothing here escalates. It accumulates: records that are missing one field each, behind a form that said Save and meant it about half of what you typed. That is the same failure as an integration reporting success while delivering nothing - a positive signal measuring something other than the thing you care about.
Sources
- Reserved item meta keys are no longer persisted in the admin - WooCommerce Developer Blog, published 18 August 2026, read 8 September 2026. The change itself, the definition of a reserved key, the "failing silently" wording for extensions, the statement that order item meta does not follow WordPress protected-meta rules, the store-owner advice about values that do not stick, and both published workarounds.
- WooCommerce issue #67440 - woocommerce/woocommerce on GitHub, opened 6 August 2026, closed 19 August 2026 as not planned, read 8 September 2026 through the GitHub API. The store owner's report of one key saving and the other vanishing, the scale of the affected site, the exchange in which the underscore reading was corrected by the change's author, the confirmation that Teams registers that key through the filter, and the closing comment including the remark that a notice might be added in a future version.
- WooCommerce issue #62328 - woocommerce/woocommerce on GitHub, opened 8 December 2025, closed by the merge of the change, read 8 September 2026 through the GitHub API. The pre-11.0 behaviour in detail: the frozen order screen, the
is_internal_meta_key was called incorrectlylog line, the invisible database rows, and the reporter's request for a message in the interface. - wc-admin-functions.php at tag 11.0.0 and at tag 10.9.0 - WooCommerce core source, read 8 September 2026. The guard, its two insertion points, and its complete absence from the previous minor release.
- OrderItemMetaUtil.php at tag 11.0.0 - WooCommerce core source, read 8 September 2026. The default hidden-key list, and reserved keys being the union of that list with the item data store's internal keys. The enlarged list described above is derived from this file together with the data stores and
class-wc-data-store-wp.phpat the same tag, and was not verified at runtime. - readme.txt at tag 11.0.0 - read 8 September 2026. The changelog entry quoted above, its position in the 11.0.0 block, and the release date of 4 August 2026.
- Teams for WooCommerce Memberships - woocommerce.com documentation, read 8 September 2026, carrying a last-modified date of 14 January 2026. The documented procedure for linking a team to a subscription through the Add meta button.
- Single Order Page and Manually Adding an Order - woocommerce.com documentation, carrying a last-modified date of 8 August 2026, read 8 September 2026, together with the archived copy from 19 May 2026. The revised description of the Add Meta button and the sentence it replaced.
- Plugin sources read on 8 September 2026 for the keys registered through the filter: Montonio for WooCommerce, Ultimate Gift Cards for WooCommerce and WooCommerce Tax. The count of 271 registrations across 245 plugins comes from a regular-expression search of the WordPress.org plugin directory sources on 8 September 2026; install counts are the directory's own figures.
Site down, or broken since the last update? Fix S — $300, 2 business days, fixed price.
Get my quote in 24hWritten by the Fixmation team.