read-only-link-requires-field - ESLint plugin rules

This rule requires read-only defineLink calls to specify a field on the first linkable, and a primaryKey or alias on the inverse form.

Severity#

error. This rule is enabled in the recommended preset.

What it Targets#

This rule targets files in your project's src/links directory. It reports read-only defineLink calls (calls whose options object sets readOnly: true) whose first argument is missing a field property. For the inverse form, where the second argument spreads <Module>.linkable.<dataModel>.id, it also requires either a primaryKey property or an alias property.

The following code is reported by the rule:

src/links/post-product.ts
1import { defineLink } from "@medusajs/framework/utils"2import BlogModule from "../modules/blog"3import ProductModule from "@medusajs/medusa/product"4
5export default defineLink(6  BlogModule.linkable.post,7  ProductModule.linkable.product,8  { readOnly: true }9)

Instead, specify the field that stores the linked record's ID on the first argument:

src/links/post-product.ts
1import { defineLink } from "@medusajs/framework/utils"2import BlogModule from "../modules/blog"3import ProductModule from "@medusajs/medusa/product"4
5export default defineLink(6  {7    linkable: BlogModule.linkable.post,8    field: "product_id",9  },10  ProductModule.linkable.product,11  { readOnly: true }12)

For the inverse form, include a primaryKey on the second argument:

src/links/post-product.ts
1export default defineLink(2  { linkable: ProductModule.linkable.product, field: "id" },3  {4    ...BlogModule.linkable.post.id,5    primaryKey: "product_id",6  },7  { readOnly: true }8)

Alternatively, you can use alias instead of primaryKey on the inverse form when re-aliasing a linkable. For example, when linking to draft orders using the order linkable re-aliased to draft_order:

src/links/quote-draft-order.ts
1import { defineLink } from "@medusajs/framework/utils"2import QuoteModule from "../modules/quote"3import OrderModule from "@medusajs/medusa/order"4
5export default defineLink(6  { linkable: QuoteModule.linkable.quote, field: "draft_order_id" },7  { ...OrderModule.linkable.order.id, alias: "draft_order" },8  { readOnly: true }9)

Why it's Important#

A read-only link doesn't store its own data, so Medusa needs the field to know where the linked record's ID lives. Without it, the link can't resolve the related records.

Learn more in the Read-Only Module Links documentation.

Fixable#

This rule isn't auto-fixable.

Was this page helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Docs MCP server in Cursor, VSCode, etc...FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break
⇧↵