{"record":{"id":"546510eac6f32aa1","repo":"medusajs/medusa","slug":"zone-property-is-missing-from-the-j-index-of","errorCode":null,"errorMessage":"'zone' property is missing from the ${j} index of the 'forms' property. The 'zone' property is required to load a custom field form.","messagePattern":"'zone' property is missing from the (.+?) index of the 'forms' property\\. The 'zone' property is required to load a custom field form\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/admin/admin-vite-plugin/src/custom-fields/generate-custom-field-forms.ts","lineNumber":294,"sourceCode":"  const formArray = getFormsArgument(path, file)\n\n  if (!formArray) {\n    return null\n  }\n\n  const forms: CustomFieldFormSection[] = []\n\n  formArray.elements.forEach((element, j) => {\n    if (!isObjectExpression(element)) {\n      return\n    }\n\n    const zoneProperty = element.properties.find(\n      (p) => isObjectProperty(p) && isIdentifier(p.key, { name: \"zone\" })\n    ) as ObjectProperty | undefined\n\n    if (!zoneProperty) {\n      logger.warn(\n        `'zone' property is missing from the ${j} index of the 'forms' property. The 'zone' property is required to load a custom field form.`,\n        { file }\n      )\n      return\n    }\n\n    if (!isStringLiteral(zoneProperty.value)) {\n      logger.warn(\n        `'zone' property at the ${j} index of the 'forms' property is not a string literal. The 'zone' property must be a string literal, e.g. 'general' or 'attributes'.`,\n        { file }\n      )\n      return\n    }\n\n    const tabProperty = element.properties.find(\n      (p) => isObjectProperty(p) && isIdentifier(p.key, { name: \"tab\" })\n    ) as ObjectProperty | undefined\n","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/admin/admin-vite-plugin/src/custom-fields/generate-custom-field-forms.ts#L276-L312","documentation":"The admin-vite-plugin statically analyzes your custom-field form definition (the array passed to the admin plugin's forms option) and requires each entry to declare a 'zone' string property. When an entry at index j has no 'zone' key, the plugin cannot determine where in the admin UI to inject the form, so it logs this warning and skips that entry. It is a build-time AST check, not a runtime error.","triggerScenarios":"An object in the 'forms' array lacks the zone key, e.g. forms: [{ tab: 'general', fields: {...} }] or forms: [{ fields: {...} }] for a custom-field form module.","commonSituations":"Copying a form config from docs that omit 'zone', migrating from an older API where only 'tab' existed, or renaming the property to 'Zone'/'formZone'.","solutions":["Add zone: 'general' (or 'attributes', 'sidebars', etc.) as a string literal to the entry at the reported index of the 'forms' array","Ensure the key is exactly 'zone' (lowercase) and a direct property of the form object, not nested inside 'fields'","Re-run the dev/build process so the plugin re-parses the file"],"exampleFix":"// before\nforms: [{ tab: 'general', fields: { myField: form.define({ ... }) } }]\n// after\nforms: [{ zone: 'general', tab: 'general', fields: { myField: form.define({ ... }) } }]","handlingStrategy":"validation","validationCode":"const entry = { tab: 'general', fields: {} }\nif (!('zone' in entry) || typeof entry.zone !== 'string') {\n  throw new Error('forms entry is missing a string zone property')\n}","typeGuard":"const isFormEntry = (e: unknown): e is { zone: string; fields: Record<string, unknown> } =>\n  typeof e === 'object' && e !== null && 'zone' in e && typeof (e as any).zone === 'string' && 'fields' in e","tryCatchPattern":null,"preventionTips":["Always start form entries from the official template with zone, tab, and fields","Treat warnings in the vite plugin output as failures in CI by grepping build logs for logger.warn output"],"tags":["admin","custom-fields","vite-plugin","config-validation"],"backgroundTag":"admin-custom-field-form-validation","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}