{"record":{"id":"ac2a7b062baa879b","repo":"payloadcms/payload","slug":"the-field-found-in-fieldschemamap-for-schemapat","errorCode":null,"errorMessage":"The field found in fieldSchemaMap for \"${schemaPath}\" does not contain any subfields.","messagePattern":"The field found in fieldSchemaMap for \"(.+?)\" does not contain any subfields\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/utilities/buildFormState.ts","lineNumber":168,"sourceCode":"    schemaMap,\n    widgetSlug,\n  })\n\n  const id = collectionSlug ? idFromArgs : undefined\n  const fieldOrEntityConfig = schemaMap.get(schemaPath)\n\n  if (!fieldOrEntityConfig) {\n    throw new Error(`Could not find \"${schemaPath}\" in the fieldSchemaMap`)\n  }\n\n  if (\n    (!('fields' in fieldOrEntityConfig) ||\n      !fieldOrEntityConfig.fields ||\n      !fieldOrEntityConfig.fields.length) &&\n    'type' in fieldOrEntityConfig &&\n    fieldOrEntityConfig.type !== 'blocks'\n  ) {\n    throw new Error(\n      `The field found in fieldSchemaMap for \"${schemaPath}\" does not contain any subfields.`,\n    )\n  }\n\n  // If there is form state but no data, deduce data from that form state, e.g. on initial load\n  // Otherwise, use the incoming data as the source of truth, e.g. on subsequent saves\n  const data = incomingData || reduceFieldsToValues(formState, true)\n\n  let documentData = undefined\n\n  if (documentFormState) {\n    documentData = reduceFieldsToValues(documentFormState, true)\n  }\n\n  let blockData = initialBlockData\n\n  if (initialBlockFormState) {\n    blockData = reduceFieldsToValues(initialBlockFormState, true)","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/ui/src/utilities/buildFormState.ts#L150-L186","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbuildFormState({ schemaPath: 'title' }) // 'title' is a text field -> no subfields\n\n// after\nbuildFormState({ schemaPath: 'items' }) // 'items' is an array field -> has subfields","handlingStrategy":"type-guard","validationCode":"const entity = schemaMap.get(schemaPath)\nconst isContainer =\n  !!entity &&\n  'fields' in entity &&\n  Array.isArray((entity as any).fields) &&\n  (entity as any).fields.length > 0\nif (!isContainer && (entity as any)?.type !== 'blocks') {\n  // schemaPath is a leaf - do not call buildFormState for it\n}","typeGuard":"function isContainerFieldSchema(\n  entity: unknown,\n): entity is { fields: unknown[]; type?: string } {\n  return (\n    !!entity &&\n    typeof entity === 'object' &&\n    'fields' in entity &&\n    Array.isArray((entity as { fields: unknown }).fields) &&\n    (entity as { fields: unknown[] }).fields.length > 0\n  )\n}\n\n// usage before buildFormState:\n// const entity = schemaMap.get(schemaPath)\n// if (Array.isArray(entity) || isContainerFieldSchema(entity) || (entity as any)?.type === 'blocks') {\n//   await buildFormState(args)\n// }","tryCatchPattern":"try {\n  await buildFormState(args)\n} catch (err) {\n  if (err instanceof Error && /does not contain any subfields/.test(err.message)) {\n    // schemaPath resolved to a leaf; skip form-state for this path\n  } else {\n    throw err\n  }\n}","preventionTips":["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."],"tags":["form-state","schema-map","field-config","validation"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}