payloadcms/payload · error · Error
The field found in fieldSchemaMap for "${schemaPath}" does n
Error message
The field found in fieldSchemaMap for "${schemaPath}" does not contain any subfields. What it means
Thrown by buildFormState when the entry resolved from the schema map at `schemaPath` has no subfields (no `fields` array, or it is empty), unless its `type` is `blocks`. The form-state builder must recurse into a container field (array, group, blocks, tabs) to produce child field state; a leaf field such as `text`, `number`, or `select` has no children to render, so the operation is undefined and rejected. The `blocks` type is exempt because its subfields are resolved dynamically from block definitions.
Source
Thrown at packages/ui/src/utilities/buildFormState.ts:168
schemaMap,
widgetSlug,
})
const id = collectionSlug ? idFromArgs : undefined
const fieldOrEntityConfig = schemaMap.get(schemaPath)
if (!fieldOrEntityConfig) {
throw new Error(`Could not find "${schemaPath}" in the fieldSchemaMap`)
}
if (
(!('fields' in fieldOrEntityConfig) ||
!fieldOrEntityConfig.fields ||
!fieldOrEntityConfig.fields.length) &&
'type' in fieldOrEntityConfig &&
fieldOrEntityConfig.type !== 'blocks'
) {
throw new Error(
`The field found in fieldSchemaMap for "${schemaPath}" does not contain any subfields.`,
)
}
// If there is form state but no data, deduce data from that form state, e.g. on initial load
// Otherwise, use the incoming data as the source of truth, e.g. on subsequent saves
const data = incomingData || reduceFieldsToValues(formState, true)
let documentData = undefined
if (documentFormState) {
documentData = reduceFieldsToValues(documentFormState, true)
}
let blockData = initialBlockData
if (initialBlockFormState) {
blockData = reduceFieldsToValues(initialBlockFormState, true)View on GitHub (pinned to 00c58b35c0)
Solutions
- Verify the `schemaPath` resolves to a container field (array/group/blocks/tabs); leaf fields (text/number/select/relationship/etc.) are invalid here.
- If using a custom field type, ensure its sanitized config exposes a non-empty `fields` array, or declare `type: 'blocks'` when subfields are resolved dynamically.
- Pass an explicit `schemaPath` in BuildFormStateArgs that points at a container entity instead of relying on the collectionSlug/globalSlug/widgetSlug default.
- Rebuild the schema map and restart the dev server after changing field config so the map matches the sanitized config.
- Inspect `schemaMap.get(schemaPath)` at runtime to confirm whether it is a single field vs. an array of entities before calling buildFormState.
Example fix
// before
buildFormState({ schemaPath: 'title' }) // 'title' is a text field -> no subfields
// after
buildFormState({ schemaPath: 'items' }) // 'items' is an array field -> has subfields Defensive patterns
Strategy: type-guard
Validate before calling
const entity = schemaMap.get(schemaPath)
const isContainer =
!!entity &&
'fields' in entity &&
Array.isArray((entity as any).fields) &&
(entity as any).fields.length > 0
if (!isContainer && (entity as any)?.type !== 'blocks') {
// schemaPath is a leaf - do not call buildFormState for it
} Type guard
function isContainerFieldSchema(
entity: unknown,
): entity is { fields: unknown[]; type?: string } {
return (
!!entity &&
typeof entity === 'object' &&
'fields' in entity &&
Array.isArray((entity as { fields: unknown }).fields) &&
(entity as { fields: unknown[] }).fields.length > 0
)
}
// usage before buildFormState:
// const entity = schemaMap.get(schemaPath)
// if (Array.isArray(entity) || isContainerFieldSchema(entity) || (entity as any)?.type === 'blocks') {
// await buildFormState(args)
// } Try / catch
try {
await buildFormState(args)
} catch (err) {
if (err instanceof Error && /does not contain any subfields/.test(err.message)) {
// schemaPath resolved to a leaf; skip form-state for this path
} else {
throw err
}
} Prevention
- Resolve schemaMap.get(schemaPath) and confirm it is an array of entities or a container field before building form state.
- Unit-test custom field types to assert they expose a non-empty `fields` array or declare `type: 'blocks'`.
- Regenerate the schema map and restart the dev server whenever field config changes.
- Pass an explicit, validated schemaPath rather than relying on the collectionSlug/globalSlug/widgetSlug default.
When it happens
Trigger: Passing a `schemaPath` (which defaults to collectionSlug/globalSlug/widgetSlug) that resolves to a scalar/leaf field rather than a container; a custom field type whose sanitized config exposes no `fields` array; a widgetSlug whose schema-map entity is a leaf; a nested path segment that names a non-container field.
Common situations: Custom field types registered without subfields, a wrong schemaPath forwarded by a custom component, schema map that is stale after field-config edits, misconfigured custom widgets, version skew between the field config and the generated schema map.
Related errors
- Either collectionSlug, globalSlug, or widgetSlug must be pro
- Invalid template given
- Invalid database type given. Valid types are: ${Object.value
- No version or tag "${version}" found for package: ${packageN
- Either collection or globalSlug must be passed.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/ac2a7b062baa879b.
Report an issue: GitHub.