{"record":{"id":"084bd000d7e6082a","repo":"medusajs/medusa","slug":"link-is-missing","errorCode":null,"errorMessage":"'link' is missing.","messagePattern":"'link' is missing\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/admin/admin-vite-plugin/src/custom-fields/generate-custom-field-links.ts","lineNumber":161,"sourceCode":"}\n\nfunction getLink(\n  path: NodePath<ExportDefaultDeclaration>,\n  index: number,\n  file: string\n): string | null {\n  const configArgument = getConfigArgument(path)\n\n  if (!configArgument) {\n    return null\n  }\n\n  const linkProperty = configArgument.properties.find(\n    (p) => isObjectProperty(p) && isIdentifier(p.key, { name: \"link\" })\n  ) as ObjectProperty | undefined\n\n  if (!linkProperty) {\n    logger.warn(`'link' is missing.`, { file })\n    return null\n  }\n\n  const import_ = generateCustomFieldConfigName(index)\n\n  return `${import_}.link`\n}\n","sourceCodeStart":143,"sourceCodeEnd":169,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/admin/admin-vite-plugin/src/custom-fields/generate-custom-field-links.ts#L143-L169","documentation":"The admin-vite-plugin generates link registrations for custom field configs. Each config passed to defineCustomFieldConfig must include a `link` property that points to the link object exported from the generated links file. When the plugin parses the config object literal and finds no `link` key, it logs this warning and skips generating the link for that custom field, so the custom field will not be linked to its module.","triggerScenarios":"Exporting a config object from src/admin/custom-fields/<name>/config.ts via defineCustomFieldConfig (or a plain default export object) that omits the `link` key.","commonSituations":"Developer creates a custom field folder with only a config.ts and forgets the accompanying links.ts; or renames/removes the link import and its usage while keeping the rest of the config.","solutions":["Open the custom field's config.ts and add a `link` property referencing the default export of ./links (e.g. `link: productCustomFieldLink`)","Ensure links.ts exists in the same folder and exports a link created with defineLink(<Model>, <ModuleModel>)","Restart the dev server so the vite plugin re-scans the custom field directories"],"exampleFix":"// before\nexport default defineCustomFieldConfig({\n  model: productCustomField,\n})\n\n// after\nimport productCustomFieldLink from \"./links\"\n\nexport default defineCustomFieldConfig({\n  model: productCustomField,\n  link: productCustomFieldLink,\n})","handlingStrategy":"validation","validationCode":"// before building, assert the config has a link key\nconst config = await import(\"./custom-fields/product/config.ts\").then(m => m.default)\nif (!config || !(\"link\" in config) || !config.link) {\n  throw new Error(\"Custom field config is missing 'link'\")\n}","typeGuard":"const hasLink = (c: unknown): c is { link: unknown } =>\n  typeof c === \"object\" && c !== null && \"link\" in c && (c as any).link != null","tryCatchPattern":null,"preventionTips":["Always scaffold custom fields in triples: config.ts + links.ts + model, and reference links.ts in config.ts","Run the dev server and treat plugin warnings as build errors during CI"],"tags":["admin","custom-fields","vite-plugin","config"],"backgroundTag":"missing-config-property","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}