medusajs/medusa · warning

'fields' property at the ${j} index of the 'forms' property

Error message

'fields' property at the ${j} index of the 'forms' property is malformed. The 'fields' property must be an object.

What it means

The getConfig equivalent of the fields-shape check: fieldsObject.value must be an ObjectExpression. Arrays, identifiers, calls, or any other node type cause this warning and the entry is skipped.

Source

Thrown at packages/admin/admin-vite-plugin/src/custom-fields/generate-custom-field-forms.ts:584

      return
    }

    const fieldsObject = element.properties.find(
      (p) => isObjectProperty(p) && isIdentifier(p.key, { name: "fields" })
    ) as ObjectProperty | undefined

    if (!fieldsObject) {
      logger.warn(
        `'fields' property is missing from the ${j} entry in the 'forms' property in ${file}.`,
        { file }
      )
      return
    }

    const fields: CustomFieldConfigField[] = []

    if (!isObjectExpression(fieldsObject.value)) {
      logger.warn(
        `'fields' property at the ${j} index of the 'forms' property is malformed. The 'fields' property must be an object.`,
        { file }
      )
      return
    }

    fieldsObject.value.properties.forEach((field) => {
      if (!isObjectProperty(field) || !isIdentifier(field.key)) {
        return
      }

      const name = field.key.name

      if (
        !isObjectExpression(field.value) &&
        !(
          isCallExpression(field.value) &&
          isMemberExpression(field.value.callee) &&

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Make 'fields' an inline object literal keyed by field name
  2. Inline any imported map
  3. Remove helper-call indirection

Example fix

// before
forms: [{ zone: 'general', fields: sharedFields }]
// after
forms: [{ zone: 'general', fields: { myField: { ... } } }]
Defensive patterns

Strategy: type-guard

Validate before calling

if (Array.isArray(f.fields) || typeof f.fields !== 'object') {
  throw new Error('fields must be an inline object literal')
}

Type guard

const isFieldsObject = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v)

Prevention

When it happens

Trigger: fields: [ ... ] array syntax, fields: importedFields variable, or fields: buildFields().

Common situations: Assuming an array like 'forms', or attempting to share/reuse field maps via imports (not possible with static analysis).

Understand the failure class

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/46b06630bd62e59b. Report an issue: GitHub.