medusajs/medusa · warning

'displays' is not an array. The 'displays' property must be

Error message

'displays' is not an array. The 'displays' property must be an array of objects.

What it means

Inside getDisplays, after finding the 'displays' property of the config export, the plugin checks that its value is an array expression in the AST. If displays is anything else (an object, an identifier referencing an array defined elsewhere, or missing braces), the config is rejected with this warning because entries cannot be enumerated.

Source

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

  index: number,
  file: string
): CustomFieldDisplay[] | null {
  const configArgument = getConfigArgument(path)

  if (!configArgument) {
    return null
  }

  const displayProperty = configArgument.properties.find(
    (p) => isObjectProperty(p) && isIdentifier(p.key, { name: "displays" })
  ) as ObjectProperty | undefined

  if (!displayProperty) {
    return null
  }

  if (!isArrayExpression(displayProperty.value)) {
    logger.warn(
      `'displays' is not an array. The 'displays' property must be an array of objects.`,
      { file }
    )
    return null
  }

  const displays: CustomFieldDisplay[] = []

  displayProperty.value.elements.forEach((element, j) => {
    if (!isObjectExpression(element)) {
      return
    }

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

    if (!zoneProperty) {

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Inline the array literally under displays: [ ... ] in the default export of the file named in the warning
  2. Move any per-entry objects into the literal array, each with zone and component properties
  3. Avoid referencing external variables for the array itself

Example fix

// before
const entries = [
  { zone: "general", component: "/src/admin/components/x" },
]
export default { model: "brand", link: "...", displays: entries }

// after
export default {
  model: "brand",
  link: "...",
  displays: [
    { zone: "general", component: "/src/admin/components/x" },
  ],
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(cfg.displays)) {
  throw new Error("'displays' must be an inline array literal in the config file")
}

Type guard

const hasDisplayArray = (c: unknown): c is { displays: unknown[] } =>
  typeof c === "object" && c !== null && Array.isArray((c as any).displays)

Try / catch

null

Prevention

When it happens

Trigger: A display config where displays is defined via a variable reference (const entries = [...]; export default { displays: entries }), an object literal, or otherwise not an inline array literal.

Common situations: Refactoring configs to share arrays between files; importing display entries from another module; typos like displays: {...} instead of [...].

Related errors


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