A PHP-only WordPress block with a list of allowed values needs the enumeration on the array's items, not merely an enum beside the array type. In a supported editor build, that schema can produce a constrained token field. Verify the saved attribute and server-rendered result as well as the visible control.
This matters when an editor should select service regions, display variants or approved categories from a small list, but can enter arbitrary text or loses the selected values after reopening a page.
Check the schema before rebuilding the inspector
The Gutenberg array-enum change, merged for the 24.1 milestone, teaches generated controls to recognize an enum inside an array's items definition.
For an existing PHP-only block registration, a small illustrative attribute definition is:
'regions' => [
'type' => 'array',
'items' => [
'type' => 'string',
'enum' => [ 'north', 'central', 'south' ],
],
'default' => [],
'autoGenerateControl' => true,
],
This is an attribute fragment, not a complete plugin. The block must already use the supported auto-registration path, including the appropriate autoRegister support. Keep registration, labels and the render callback in the plugin's source, not in an unrelated theme template.
Do not infer feature availability just because the site runs a recent WordPress version. Record the exact editor build and whether Gutenberg is active. A plugin that bundles its own editor code also needs its dependency versions checked.
Build a three-choice fixture
Use a private staging draft with one instance of the block. Start empty, select north and south, save, and reopen. Compare four layers: the offered choices, selected tokens, stored attribute and rendered text.
The expected shape for that example is an array of strings, such as ["north","south"]. Do not accept a comma-separated string as equivalent just because it looks similar on screen.
Next remove one token, save and reopen again. Finally clear the field and confirm that the renderer handles an empty array without warnings or fallback content that contradicts the empty selection.
Schema: items.enum defines choices. Selection: Multiple tokens form an array. Storage: Save and reopen without drift. Rendering: Empty and old values handled. Proposed verification, not a customer test result.
Keep these checks separate:
| Symptom |
Likely boundary to investigate |
| Free text accepted where choices are expected |
Schema location, generated-control support or stale editor bundle |
| Selection disappears after save |
Attribute serialization, validation or update path |
| Saved array is correct but output is wrong |
Render callback or presentation mapping |
| Old content contains removed choices |
Schema migration and compatibility policy |
| Empty selection raises a warning |
Renderer assumptions about missing or empty values |
Do not treat the picker as server-side authorization
A constrained control is an editing aid. It does not replace permission checks or validation at a custom API boundary. If another integration can write the field, validate its accepted values on that path too.
In the render callback, handle an absent attribute and escape text for the output context. Do not render arbitrary input as HTML because a token picker usually supplies known strings. Avoid silently converting unknown persisted values into a different business meaning.
For example, removing a service-region value from the schema can affect old posts. Decide whether those records retain the old label, show a deliberate warning or undergo a reviewed migration. Test existing content before shipping the narrower list.
Separate generated block fields from post panels
An inspector field belonging to a block is not the same as a plugin's post excerpt panel. If a whole post sidebar integration vanished, use the DataForm inspector diagnostic instead.
That distinction prevents a common detour: rebuilding a sidebar extension when the actual problem is one attribute definition. If the schema is correct but the generated UI and stored data still disagree, HandL WP can trace the block's save and render path.
Release acceptance
Test an existing post, a new post, empty selection, multiple choices and a deliberately outdated stored value on staging. Confirm the public page renders the intended content after caches refresh.
Keep the fixture data and expected outputs in the plugin's tests. Label any screenshots as test fixtures, and record the supported editor version. The result should be a predictable editing contract, not just a token field that appears once during development.
References reviewed October 19, 2026. Diagrams and test fixtures are explanatory, not customer results.