Summary
Every group field renders its header and an empty .render-fields container. None of its child fields are rendered, in the server HTML or after hydration. Sibling fields outside the group render normally, and array, row, tabs and collapsible all render their children correctly. Only group is affected.
The field definitions and their values do reach the client — they appear in the serialized form state — so the schema is transmitted and the children are dropped at render time.
Reproduction
Minimal app: no plugins, no custom components, no hooks, empty import map.
// payload.config.ts
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { buildConfig } from 'payload'
export default buildConfig({
secret: process.env.PAYLOAD_SECRET!,
db: mongooseAdapter({ url: process.env.MONGODB_URI! }),
admin: { user: 'users' },
collections: [{ slug: 'users', auth: true, fields: [] }],
globals: [
{
slug: 'group-repro',
fields: [
{ name: 'before', type: 'text', label: 'Control field, outside the group' },
{
name: 'grp',
type: 'group',
label: 'Group with direct children',
fields: [
{ name: 'x', type: 'text', label: 'Field X' },
{ name: 'y', type: 'text', label: 'Field Y' },
],
},
],
},
],
})
Open /admin/globals/group-repro.
Expected: inputs before, grp.x, grp.y.
Actual: only before. The group renders as:
<div class="group-field__wrap">
<div class="group-field__header">
<header><h3 class="group-field__title"><span class="field-label" for="field-grp">Group with direct children</span></h3></header>
</div>
<div class="render-fields render-fields--margins-small"></div> <!-- empty -->
</div>
GroupField runs and calls RenderFields; RenderFields produces an empty list.
Evidence that the schema reaches the client
Comparing a working array child with a broken group child, in the raw server HTML:
arr.0.a → <input name="arr.0.a" value="5"/> (rendered)
+ "arr.0.a":{"value":5,"initialValue":5} (form state)
grp.x → "grp.x":{"value":7,"initialValue":7} (form state only)
no <input> anywhere
The group's _index-0 row entry is present in the form state too. The values are known; the fields are simply never rendered.
What was ruled out
| Variable |
Values tested |
Result |
| Payload |
3.84.1, 3.85.0, 3.88.0 |
broken in all |
| Next |
15.4.11, 16.2.6 |
broken in both |
| Bundler |
Turbopack, webpack |
broken in both |
| Node |
22.x, 24.x, 26.5.1 |
broken in all |
| Group shape |
direct children / a single row / a direct child then a row |
broken in all |
admin.readOnly on the group |
present / absent |
broken in both |
Field-level access on the group |
present / absent |
broken in both |
| Custom admin components |
present / none / empty import map |
broken in all |
Root admin.components.providers, Nav |
present / removed |
broken in both |
| Admin layout |
customised / bare Payload template |
broken in both |
| Dependency tree |
existing project / fresh npm install in an empty folder |
broken in both |
| Collection vs global |
four different collections and globals |
broken in all |
Also checked: no console errors (so no React error boundary); /api/access returns an empty fields object for every collection and global — including for fields that render correctly, so it is not a discriminator; no overrides, resolutions or patches on any Payload package; and no CSP on the admin route.
Sibling container types (array, row, tabs, collapsible) render their children correctly in the same admin, on the same page.
Environment
- payload / @payloadcms/next / @payloadcms/ui / @payloadcms/db-mongodb / @payloadcms/richtext-lexical: 3.88.0 (all aligned)
- next: 15.4.11
- react / react-dom: 19.2.8
- node: 26.5.1 (also reproduced on 22.x and 24.x)
- database: MongoDB Atlas
- OS: macOS (darwin 23.4.0)
Impact
Any setting modelled as a group becomes uneditable from the admin: the values are stored and applied correctly by the API, but no one can reach them through the UI. We have worked around it with dedicated ui field components that read and write through the REST API, which is workable but has to be repeated for every group.
Summary
Every
groupfield renders its header and an empty.render-fieldscontainer. None of its child fields are rendered, in the server HTML or after hydration. Sibling fields outside the group render normally, andarray,row,tabsandcollapsibleall render their children correctly. Onlygroupis affected.The field definitions and their values do reach the client — they appear in the serialized form state — so the schema is transmitted and the children are dropped at render time.
Reproduction
Minimal app: no plugins, no custom components, no hooks, empty import map.
Open
/admin/globals/group-repro.Expected: inputs
before,grp.x,grp.y.Actual: only
before. The group renders as:GroupFieldruns and callsRenderFields;RenderFieldsproduces an empty list.Evidence that the schema reaches the client
Comparing a working
arraychild with a brokengroupchild, in the raw server HTML:The group's
_index-0row entry is present in the form state too. The values are known; the fields are simply never rendered.What was ruled out
row/ a direct child then arowadmin.readOnlyon the groupaccesson the groupadmin.components.providers,Navnpm installin an empty folderAlso checked: no console errors (so no React error boundary);
/api/accessreturns an emptyfieldsobject for every collection and global — including for fields that render correctly, so it is not a discriminator; nooverrides,resolutionsor patches on any Payload package; and no CSP on the admin route.Sibling container types (
array,row,tabs,collapsible) render their children correctly in the same admin, on the same page.Environment
Impact
Any setting modelled as a
groupbecomes uneditable from the admin: the values are stored and applied correctly by the API, but no one can reach them through the UI. We have worked around it with dedicateduifield components that read and write through the REST API, which is workable but has to be repeated for every group.