medusajs/medusa · warning

'tab' property at the ${j} index of the 'forms' property is

Error message

'tab' property at the ${j} index of the 'forms' property is not a valid custom field form tab for the '${model}' model. Received: ${tab}.

What it means

A 'tab' value was supplied as a string literal, but the string does not match any tab supported by the given model's form. The plugin validates the tab via isValidCustomFieldFormTab(tab) and rejects unknown values, since there is no UI tab to render the form in.

Source

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

      (p) => isObjectProperty(p) && isIdentifier(p.key, { name: "tab" })
    ) as ObjectProperty | undefined

    let tab: string | undefined

    if (tabProperty) {
      if (!isStringLiteral(tabProperty.value)) {
        logger.warn(
          `'tab' property at the ${j} index of the 'forms' property is not a string literal. The 'tab' property must be a string literal, e.g. 'general' or 'attributes'.`,
          { file }
        )
        return
      }

      tab = tabProperty.value.value
    }

    if (tab && !isValidCustomFieldFormTab(tab)) {
      logger.warn(
        `'tab' property at the ${j} index of the 'forms' property is not a valid custom field form tab for the '${model}' model. Received: ${tab}.`,
        { file }
      )
      return
    }

    const zone = zoneProperty.value.value
    const fullPath = getFormEntryFieldPath(model, zone, tab)

    if (
      !isValidCustomFieldFormZone(zone) ||
      !isValidCustomFieldFormFieldPath(fullPath)
    ) {
      logger.warn(
        `'zone' and 'tab' properties at the ${j} index of the 'forms' property are not a valid for the '${model}' model. Received: { zone: ${zone}, tab: ${tab} }.`,
        { file }
      )
      return

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Check the model's supported form tabs in the Medusa admin docs and use one of those exact strings
  2. Fix typos in the tab value
  3. If the intended tab does not exist for the model, drop 'tab' and rely on the zone default

Example fix

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

Strategy: validation

Validate before calling

const VALID_TABS = ['general', 'attributes']
if (f.tab && !VALID_TABS.includes(f.tab)) {
  throw new Error(`unsupported tab '${f.tab}' for model ${model}`)
}

Type guard

const isValidTab = (t: string) => ['general', 'attributes'].includes(t)

Prevention

When it happens

Trigger: tab: 'pricing' for a model whose form only exposes 'general'/'attributes', or a typo like tab: 'genral'.

Common situations: Assuming tabs from one model (e.g. product) apply to another (e.g. customer), version upgrades that renamed tabs, or simple typos.

Related errors


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