[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-strapi-strapi-version-upgrade":3,"mdc--wwdye8-key":31,"related-repo-strapi-strapi-version-upgrade":1874,"related-org-strapi-strapi-version-upgrade":1911},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":26,"sourceUrl":29,"mdContent":30},"strapi-version-upgrade","upgrade Strapi applications to new versions","Upgrade a Strapi application to a new version. ALWAYS reviews the relevant breaking changes first (via the strapi-docs MCP server, or by fetching the docs directly if the MCP is unavailable), then performs the upgrade using the official @strapi\u002Fupgrade tool. Use whenever the user wants to upgrade, update, or bump their Strapi version.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"strapi","Strapi","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fstrapi.png",[12,14,17],{"name":9,"slug":8,"type":13},"tag",{"name":15,"slug":16,"type":13},"CMS","cms",{"name":18,"slug":19,"type":13},"Migration","migration",2,"https:\u002F\u002Fgithub.com\u002Fstrapi\u002Fskills","2026-07-19T06:03:45.306446",null,1,[],{"repoUrl":21,"stars":20,"forks":24,"topics":27,"description":28},[],"AI Agent Skills A collection of skills for AI coding agents. Skills are packaged instructions and scripts that extend agent capabilities.","https:\u002F\u002Fgithub.com\u002Fstrapi\u002Fskills\u002Ftree\u002FHEAD\u002Fskills\u002Fcms\u002Fstrapi-version-upgrade","---\nname: strapi-version-upgrade\ndescription: Upgrade a Strapi application to a new version. ALWAYS reviews the relevant breaking changes first (via the strapi-docs MCP server, or by fetching the docs directly if the MCP is unavailable), then performs the upgrade using the official @strapi\u002Fupgrade tool. Use whenever the user wants to upgrade, update, or bump their Strapi version.\n---\n\n# Strapi version upgrade\n\nUpgrade a Strapi project to a target version. This skill enforces two hard rules:\n\n1. **Always check breaking changes before upgrading.** Never run the upgrade without first reviewing the breaking changes that apply between the current version and the target.\n2. **Always use the `@strapi\u002Fupgrade` tool to perform the upgrade.** Never upgrade by manually editing `package.json` or running `npm install @strapi\u002Fstrapi@x` directly.\n\nFollow the steps below in order.\n\n## Step 1 — Determine current and target versions\n\n1. Read the project's current Strapi version from `package.json` (`@strapi\u002Fstrapi` under `dependencies`). If there is no Strapi project in the working directory, stop and tell the user.\n2. Determine the latest published version:\n\n   ```bash\n   npm view @strapi\u002Fstrapi dist-tags\n   ```\n\n   The `latest` tag is the newest stable release. `legacy` is typically the latest v4.\n\n3. Establish the target. If the user named a version or release type (`major`\u002F`minor`\u002F`patch`\u002F`latest`\u002Fa specific `x.y.z`), use it. Otherwise default to `latest` and confirm with the user.\n4. Classify the jump using [semantic versioning](https:\u002F\u002Fsemver.org\u002F): compare the major\u002Fminor\u002Fpatch of current vs. target. **Only a change in the major number introduces breaking changes.** Minor and patch releases are backward-compatible by definition.\n\n## Step 2 — Check breaking changes (MANDATORY, before any upgrade)\n\nUse the `strapi-docs-mcp` skill \u002F `strapi-docs` MCP server if it is available; otherwise fetch the docs directly. Do not skip this step even for patch upgrades.\n\n### If the strapi-docs MCP server is available\n\nQuery it for the breaking changes between the current and target versions, e.g.:\n\n> \"What are the breaking changes when upgrading Strapi from `\u003Ccurrent>` to `\u003Ctarget>`?\"\n\nQuote the exact breaking-change titles and note which are handled by codemods vs. which require manual work.\n\n### If the MCP server is NOT available\n\nFetch the breaking changes page directly (no auth needed). Prefer the flat Markdown form:\n\n- Major-version migrations (e.g. v4 → v5): `https:\u002F\u002Fdocs.strapi.io\u002Fcms\u002Fmigration\u002Fv4-to-v5\u002Fbreaking-changes.md`\n\nUse `WebFetch` on the `.md` URL (append `.md` to any `docs.strapi.io` page to get flattened Markdown with nothing hidden in tabs\u002Faccordions). If a page 404s as `.md`, retry the HTML URL.\n\n### Make the report concrete — scan the codebase\n\nDo not stop at a generic list from the docs. For each breaking change, **grep the project's own source to see which ones actually apply**, and turn the summary into a project-specific list. Concretely:\n\n- Read `src\u002Findex.{js,ts}` (the app's `register`\u002F`bootstrap` entry) for patterns the breaking changes touch.\n- Scan the project's controllers, services, and route files (`src\u002Fapi\u002F**`) — the upgrade tool's codemods cover common patterns, but custom logic often uses APIs a breaking change renames or removes.\n- Read the content-type schemas (`src\u002Fapi\u002F**\u002Fcontent-types\u002F**\u002Fschema.json` and `src\u002Fcomponents\u002F**`) for attributes affected by breaking changes — e.g. attribute types that changed, or attribute names that collide with new reserved\u002Fsystem names.\n- Check `package.json` and `config\u002Fplugins.{js,ts}` for third-party plugins whose compatibility may be affected.\n\nUse each breaking-change title as a search seed (grep for the removed\u002Frenamed API, the deprecated option, the reserved name). Report **which files match which breaking change** so the user sees exactly what the upgrade will touch versus what they'll need to fix by hand.\n\n### Report and gate\n\n- **Same major (minor\u002Fpatch upgrade):** State clearly that there are **no breaking changes** — the breaking-changes database is scoped to major migrations only. You still performed the check; say so.\n- **Major upgrade:** Summarize the applicable breaking changes grounded in the codebase scan above, flag which are handled by codemods versus which need manual code updates, call out any **reserved-name collisions** (these may need a database migration — see Step 7), and **stop and wait for the user's affirmative reply before proceeding — do not continue in the same turn.**\n\n## Step 3 — Pre-flight safety\n\nRemind the user to back up **codebase and database** before upgrading (default SQLite DB is `.tmp\u002Fdata.db`). The upgrade tool also checks for a clean git working tree as an optional requirement, so a committed\u002Fclean tree eases rollback.\n\nOffer a dry run first to preview changes without modifying files:\n\n```bash\nnpx @strapi\u002Fupgrade \u003Ctarget> --dry\n```\n\n## Step 4 — Check the running Node version (before running the tool)\n\nThe `@strapi\u002Fupgrade` tool is itself a Node CLI: it runs under whatever Node `npx` is invoked with, and it declares the **same** Node requirement as the target Strapi. So the running Node — not just `package.json`'s `engines` — must satisfy the target's range **before** you run the tool. If it doesn't, both the upgrade run and the subsequent app boot happen on an unsupported runtime.\n\n1. Read the currently running Node version (`node -v`).\n2. Read the Node range the **target** Strapi supports:\n\n   ```bash\n   npm view @strapi\u002Fstrapi@\u003Ctarget-x.y.z> engines\n   ```\n\n   (Cross-check against the docs' recommended Node for that major — Strapi recommends the active LTS.)\n\n3. **If the running Node already satisfies the target's range**, continue to Step 5.\n4. **If it does not, Node must be upgraded before the upgrade.** How you handle this depends on whether the user has a **Node version manager** — check for one before deciding (look for `nvm`, `fnm`, or `volta` on `PATH`, and for a `.nvmrc` \u002F `.node-version` \u002F Volta field in the repo):\n   - **If a version manager is present:** **prompt the user to ask whether they want you to upgrade the Node version** for them, and gate on their confirmation before any runtime change. Only if they confirm:\n     - Pick a Node version **inside the target's range**, preferring an LTS release the target lists.\n     - Switch via their version manager (never a global install) so the change is reversible — the old Strapi can still run on the old Node if a rollback is needed. Suggest pinning it in the repo (`.nvmrc` \u002F `.node-version` \u002F Volta field) so CI and teammates move together.\n   - **If no version manager is present:** do **not** attempt to change the system Node yourself — a global runtime swap is risky and not cleanly reversible. Instead, **tell the user to fix the Node version on their own**, and recommend they do it by **installing a version manager first** (`nvm`, `fnm`, or `volta`), then selecting a Node version inside the target's range. Stop and wait for them to sort the runtime out before continuing.\n   - **Do not reinstall `node_modules` immediately after switching Node.** At that point `package.json` still pins the **old** Strapi, so a clean install would rebuild the _old_ dependency tree against the new Node — which, if the ranges are disjoint (below), can fail the `engines` check or leave native modules built against the wrong ABI, breaking the working state before the tool has moved you forward. The clean reinstall belongs **after** Step 5, once the tool has rewritten `package.json` to the target (see Step 7d).\n   - **When the current and target Node ranges do not overlap at all** (e.g. current supports Node 18, target requires ≥20), a clean in-place swap isn't possible while staying on the old runtime. The safe ordering is: on the **old** Node, first get the current major to its **latest patch** (run `npx @strapi\u002Fupgrade minor`), so that step stays rollback-able; _then_ switch Node into the target's range; _then_ run the major upgrade in Step 5. Only after that upgrade run do you reinstall dependencies.\n\n## Step 5 — Run the upgrade with the upgrade tool\n\nRun the official tool from the project root. Choose the command form that matches the target:\n\n```bash\nnpx @strapi\u002Fupgrade latest          # newest stable version\nnpx @strapi\u002Fupgrade major           # next major (requires being on latest patch of current major first)\nnpx @strapi\u002Fupgrade minor           # latest minor+patch in current major\nnpx @strapi\u002Fupgrade patch           # latest patch in current minor\nnpx @strapi\u002Fupgrade to \u003Cx.y.z>      # a specific published version\n```\n\nNotes:\n\n- `major` is gated: the project must already be on the latest patch of its current major. If it isn't, run `minor` first, then `major`.\n- Use `to \u003Cx.y.z>` when `latest` is blocked by a registry policy (e.g. `min-release-age` in `.npmrc`) or when the user wants an exact version. `to` skips the major-safety check intentionally.\n- For pre-releases, add `--codemods-target \u003Cx.y.z>`.\n- Useful flags: `-y\u002F--yes` (auto-confirm prompts), `-d\u002F--debug` (verbose), `-p\u002F--project-path \u003Cpath>` (non-cwd project). **Avoid `-y\u002F--yes` for major jumps** — it auto-confirms *every* prompt, including the major-version safety prompt on `latest`. Prefer interactive mode (or explicit per-step user approval) unless the user asked for an unattended run.\n\nThe tool updates dependencies, installs them, and runs codemods for the target version. **Do not** substitute a manual `package.json` edit or a bare `npm install` for this step.\n\nIf the install phase fails (e.g. `ERESOLVE`), first retry with a **clean `node_modules` and lockfile** (`rm -rf node_modules package-lock.json && npm install`) before falling back to any manual dependency edits — a stale lockfile from the old major is the most common cause and a clean reinstall usually resolves it.\n\n## Step 6 — Fix the `engines` field\n\nThe upgrade tool updates dependencies but **does not touch `package.json`'s `engines` field**. A stale `engines.node` range left over from the old major can fail the compatibility check and **block `install`** (`npm`\u002F`yarn`\u002F`pnpm`) after the upgrade. (This is the declared range in `package.json` — distinct from the _running_ Node you checked in Step 4.)\n\n1. Read `engines` from the project's `package.json`.\n2. Reuse the target's Node range from Step 4 (`npm view @strapi\u002Fstrapi@\u003Ctarget-x.y.z> engines`).\n3. If the project's `engines.node` is narrower than or incompatible with the target's, **offer to replace it** with the correct range for the target major, and apply the edit once the user confirms. Leave it alone if it's already compatible.\n\n## Step 7 — Post-upgrade: codemod gaps, plugins, migrations\n\nRun these in order. Each destructive or code-changing action **pauses for the user to confirm** — the user is in charge of every change beyond what the tool applied automatically.\n\n### 7a — Review and offer to fix the codemod gaps\n\n1. Tell the user to **review the changes** the tool made (especially codemod edits and `package.json`) before restarting the app.\n2. Codemods cover common patterns, not everything. Cross-reference the breaking changes flagged as \"manual\" in Step 2 against the code the codemods actually changed. For anything still unhandled, **ask the user whether they want you to attempt the fixes** in application code — then **wait for their affirmative reply; do not start editing in the same turn.** Only edit code after they confirm, and edit _after_ the tool's codemods have been applied (never before — you'd fight the codemods).\n\n### 7b — Upgrade incompatible third-party plugins\n\nIf any third-party plugin (from Step 2's `package.json`\u002F`config\u002Fplugins` scan, or surfaced by install\u002Fboot errors) is **not compatible** with the target Strapi version:\n\n1. Identify a plugin version that supports the target (`npm view \u003Cplugin> versions` \u002F its peer-dependency range on `@strapi\u002Fstrapi`).\n2. **Ask the user before upgrading each plugin individually** — confirm every plugin bump separately; never batch-upgrade plugins silently.\n3. Apply the confirmed version bump and reinstall.\n\n### 7c — Reserved-name collisions → custom database migration\n\nIf Step 2 found an attribute whose name collides with a new **reserved\u002Fsystem name** in the target major, a rename is required and renaming a column risks data loss. In that case:\n\n1. **Ask the user whether to proceed with the rename** at all.\n2. If yes, **ask whether you should generate a database migration** to preserve existing data during the rename.\n3. **Require an explicit backup confirmation before writing or running any migration.** The migration executes against the real database on next boot and the rename is not cleanly reversible, so ask the user to confirm **they have manually backed up the database** — then **stop and wait for a clear \"yes\" in a separate reply; do not continue in the same turn.** Do not proceed on a vague answer, and never take the backup on their behalf as a substitute for their confirmation. If they have not backed up, stop and let them do it first.\n4. Only after that confirmation, author the migration following **[reference.md](reference.md)** (placement, ordering gotchas, data-safe rename, system-column collisions, idempotency, `down()`). Do not hand-wave this — the ordering and collision rules there prevent both boot failures and silent data loss.\n\n### 7d — Verify\n\n1. For major upgrades, note that Strapi's built-in data migrations run automatically on first startup in the new major — the upgrade tool does **not** migrate data itself, and any custom migration in `.\u002Fdatabase\u002Fmigrations\u002F` also runs then.\n2. **If Node was switched in Step 4, do a clean reinstall now** — after the tool has rewritten `package.json` to the target, not before: `rm -rf node_modules && install`. Native modules (`better-sqlite3`, `sharp`, …) are compiled against a specific Node ABI; a stale build left over from the old Node is the most common \"changed Node and it won't boot\" failure and is easily misread as an upgrade bug.\n3. Verify: reinstall if needed, rebuild the admin, and start the app to confirm it boots cleanly.\n",{"data":32,"body":33},{"name":4,"description":6},{"type":34,"children":35},"root",[36,44,50,101,106,113,281,287,308,315,320,345,350,356,361,376,419,425,437,521,533,539,581,587,607,612,659,665,712,1073,1079,1084,1217,1222,1361,1388,1422,1435,1514,1565,1571,1583,1589,1636,1642,1668,1705,1711,1723,1795,1801,1868],{"type":37,"tag":38,"props":39,"children":40},"element","h1",{"id":4},[41],{"type":42,"value":43},"text","Strapi version upgrade",{"type":37,"tag":45,"props":46,"children":47},"p",{},[48],{"type":42,"value":49},"Upgrade a Strapi project to a target version. This skill enforces two hard rules:",{"type":37,"tag":51,"props":52,"children":53},"ol",{},[54,66],{"type":37,"tag":55,"props":56,"children":57},"li",{},[58,64],{"type":37,"tag":59,"props":60,"children":61},"strong",{},[62],{"type":42,"value":63},"Always check breaking changes before upgrading.",{"type":42,"value":65}," Never run the upgrade without first reviewing the breaking changes that apply between the current version and the target.",{"type":37,"tag":55,"props":67,"children":68},{},[69,83,85,91,93,99],{"type":37,"tag":59,"props":70,"children":71},{},[72,74,81],{"type":42,"value":73},"Always use the ",{"type":37,"tag":75,"props":76,"children":78},"code",{"className":77},[],[79],{"type":42,"value":80},"@strapi\u002Fupgrade",{"type":42,"value":82}," tool to perform the upgrade.",{"type":42,"value":84}," Never upgrade by manually editing ",{"type":37,"tag":75,"props":86,"children":88},{"className":87},[],[89],{"type":42,"value":90},"package.json",{"type":42,"value":92}," or running ",{"type":37,"tag":75,"props":94,"children":96},{"className":95},[],[97],{"type":42,"value":98},"npm install @strapi\u002Fstrapi@x",{"type":42,"value":100}," directly.",{"type":37,"tag":45,"props":102,"children":103},{},[104],{"type":42,"value":105},"Follow the steps below in order.",{"type":37,"tag":107,"props":108,"children":110},"h2",{"id":109},"step-1-determine-current-and-target-versions",[111],{"type":42,"value":112},"Step 1 — Determine current and target versions",{"type":37,"tag":51,"props":114,"children":115},{},[116,144,209,258],{"type":37,"tag":55,"props":117,"children":118},{},[119,121,126,128,134,136,142],{"type":42,"value":120},"Read the project's current Strapi version from ",{"type":37,"tag":75,"props":122,"children":124},{"className":123},[],[125],{"type":42,"value":90},{"type":42,"value":127}," (",{"type":37,"tag":75,"props":129,"children":131},{"className":130},[],[132],{"type":42,"value":133},"@strapi\u002Fstrapi",{"type":42,"value":135}," under ",{"type":37,"tag":75,"props":137,"children":139},{"className":138},[],[140],{"type":42,"value":141},"dependencies",{"type":42,"value":143},"). If there is no Strapi project in the working directory, stop and tell the user.",{"type":37,"tag":55,"props":145,"children":146},{},[147,149,187,191,193,199,201,207],{"type":42,"value":148},"Determine the latest published version:",{"type":37,"tag":150,"props":151,"children":156},"pre",{"className":152,"code":153,"language":154,"meta":155,"style":155},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npm view @strapi\u002Fstrapi dist-tags\n","bash","",[157],{"type":37,"tag":75,"props":158,"children":159},{"__ignoreMap":155},[160],{"type":37,"tag":161,"props":162,"children":164},"span",{"class":163,"line":24},"line",[165,171,177,182],{"type":37,"tag":161,"props":166,"children":168},{"style":167},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[169],{"type":42,"value":170},"npm",{"type":37,"tag":161,"props":172,"children":174},{"style":173},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[175],{"type":42,"value":176}," view",{"type":37,"tag":161,"props":178,"children":179},{"style":173},[180],{"type":42,"value":181}," @strapi\u002Fstrapi",{"type":37,"tag":161,"props":183,"children":184},{"style":173},[185],{"type":42,"value":186}," dist-tags\n",{"type":37,"tag":188,"props":189,"children":190},"br",{},[],{"type":42,"value":192},"The ",{"type":37,"tag":75,"props":194,"children":196},{"className":195},[],[197],{"type":42,"value":198},"latest",{"type":42,"value":200}," tag is the newest stable release. ",{"type":37,"tag":75,"props":202,"children":204},{"className":203},[],[205],{"type":42,"value":206},"legacy",{"type":42,"value":208}," is typically the latest v4.",{"type":37,"tag":55,"props":210,"children":211},{},[212,214,220,222,228,229,235,236,241,243,249,251,256],{"type":42,"value":213},"Establish the target. If the user named a version or release type (",{"type":37,"tag":75,"props":215,"children":217},{"className":216},[],[218],{"type":42,"value":219},"major",{"type":42,"value":221},"\u002F",{"type":37,"tag":75,"props":223,"children":225},{"className":224},[],[226],{"type":42,"value":227},"minor",{"type":42,"value":221},{"type":37,"tag":75,"props":230,"children":232},{"className":231},[],[233],{"type":42,"value":234},"patch",{"type":42,"value":221},{"type":37,"tag":75,"props":237,"children":239},{"className":238},[],[240],{"type":42,"value":198},{"type":42,"value":242},"\u002Fa specific ",{"type":37,"tag":75,"props":244,"children":246},{"className":245},[],[247],{"type":42,"value":248},"x.y.z",{"type":42,"value":250},"), use it. Otherwise default to ",{"type":37,"tag":75,"props":252,"children":254},{"className":253},[],[255],{"type":42,"value":198},{"type":42,"value":257}," and confirm with the user.",{"type":37,"tag":55,"props":259,"children":260},{},[261,263,272,274,279],{"type":42,"value":262},"Classify the jump using ",{"type":37,"tag":264,"props":265,"children":269},"a",{"href":266,"rel":267},"https:\u002F\u002Fsemver.org\u002F",[268],"nofollow",[270],{"type":42,"value":271},"semantic versioning",{"type":42,"value":273},": compare the major\u002Fminor\u002Fpatch of current vs. target. ",{"type":37,"tag":59,"props":275,"children":276},{},[277],{"type":42,"value":278},"Only a change in the major number introduces breaking changes.",{"type":42,"value":280}," Minor and patch releases are backward-compatible by definition.",{"type":37,"tag":107,"props":282,"children":284},{"id":283},"step-2-check-breaking-changes-mandatory-before-any-upgrade",[285],{"type":42,"value":286},"Step 2 — Check breaking changes (MANDATORY, before any upgrade)",{"type":37,"tag":45,"props":288,"children":289},{},[290,292,298,300,306],{"type":42,"value":291},"Use the ",{"type":37,"tag":75,"props":293,"children":295},{"className":294},[],[296],{"type":42,"value":297},"strapi-docs-mcp",{"type":42,"value":299}," skill \u002F ",{"type":37,"tag":75,"props":301,"children":303},{"className":302},[],[304],{"type":42,"value":305},"strapi-docs",{"type":42,"value":307}," MCP server if it is available; otherwise fetch the docs directly. Do not skip this step even for patch upgrades.",{"type":37,"tag":309,"props":310,"children":312},"h3",{"id":311},"if-the-strapi-docs-mcp-server-is-available",[313],{"type":42,"value":314},"If the strapi-docs MCP server is available",{"type":37,"tag":45,"props":316,"children":317},{},[318],{"type":42,"value":319},"Query it for the breaking changes between the current and target versions, e.g.:",{"type":37,"tag":321,"props":322,"children":323},"blockquote",{},[324],{"type":37,"tag":45,"props":325,"children":326},{},[327,329,335,337,343],{"type":42,"value":328},"\"What are the breaking changes when upgrading Strapi from ",{"type":37,"tag":75,"props":330,"children":332},{"className":331},[],[333],{"type":42,"value":334},"\u003Ccurrent>",{"type":42,"value":336}," to ",{"type":37,"tag":75,"props":338,"children":340},{"className":339},[],[341],{"type":42,"value":342},"\u003Ctarget>",{"type":42,"value":344},"?\"",{"type":37,"tag":45,"props":346,"children":347},{},[348],{"type":42,"value":349},"Quote the exact breaking-change titles and note which are handled by codemods vs. which require manual work.",{"type":37,"tag":309,"props":351,"children":353},{"id":352},"if-the-mcp-server-is-not-available",[354],{"type":42,"value":355},"If the MCP server is NOT available",{"type":37,"tag":45,"props":357,"children":358},{},[359],{"type":42,"value":360},"Fetch the breaking changes page directly (no auth needed). Prefer the flat Markdown form:",{"type":37,"tag":362,"props":363,"children":364},"ul",{},[365],{"type":37,"tag":55,"props":366,"children":367},{},[368,370],{"type":42,"value":369},"Major-version migrations (e.g. v4 → v5): ",{"type":37,"tag":75,"props":371,"children":373},{"className":372},[],[374],{"type":42,"value":375},"https:\u002F\u002Fdocs.strapi.io\u002Fcms\u002Fmigration\u002Fv4-to-v5\u002Fbreaking-changes.md",{"type":37,"tag":45,"props":377,"children":378},{},[379,381,387,389,395,397,402,404,410,412,417],{"type":42,"value":380},"Use ",{"type":37,"tag":75,"props":382,"children":384},{"className":383},[],[385],{"type":42,"value":386},"WebFetch",{"type":42,"value":388}," on the ",{"type":37,"tag":75,"props":390,"children":392},{"className":391},[],[393],{"type":42,"value":394},".md",{"type":42,"value":396}," URL (append ",{"type":37,"tag":75,"props":398,"children":400},{"className":399},[],[401],{"type":42,"value":394},{"type":42,"value":403}," to any ",{"type":37,"tag":75,"props":405,"children":407},{"className":406},[],[408],{"type":42,"value":409},"docs.strapi.io",{"type":42,"value":411}," page to get flattened Markdown with nothing hidden in tabs\u002Faccordions). If a page 404s as ",{"type":37,"tag":75,"props":413,"children":415},{"className":414},[],[416],{"type":42,"value":394},{"type":42,"value":418},", retry the HTML URL.",{"type":37,"tag":309,"props":420,"children":422},{"id":421},"make-the-report-concrete-scan-the-codebase",[423],{"type":42,"value":424},"Make the report concrete — scan the codebase",{"type":37,"tag":45,"props":426,"children":427},{},[428,430,435],{"type":42,"value":429},"Do not stop at a generic list from the docs. For each breaking change, ",{"type":37,"tag":59,"props":431,"children":432},{},[433],{"type":42,"value":434},"grep the project's own source to see which ones actually apply",{"type":42,"value":436},", and turn the summary into a project-specific list. Concretely:",{"type":37,"tag":362,"props":438,"children":439},{},[440,468,481,502],{"type":37,"tag":55,"props":441,"children":442},{},[443,445,451,453,459,460,466],{"type":42,"value":444},"Read ",{"type":37,"tag":75,"props":446,"children":448},{"className":447},[],[449],{"type":42,"value":450},"src\u002Findex.{js,ts}",{"type":42,"value":452}," (the app's ",{"type":37,"tag":75,"props":454,"children":456},{"className":455},[],[457],{"type":42,"value":458},"register",{"type":42,"value":221},{"type":37,"tag":75,"props":461,"children":463},{"className":462},[],[464],{"type":42,"value":465},"bootstrap",{"type":42,"value":467}," entry) for patterns the breaking changes touch.",{"type":37,"tag":55,"props":469,"children":470},{},[471,473,479],{"type":42,"value":472},"Scan the project's controllers, services, and route files (",{"type":37,"tag":75,"props":474,"children":476},{"className":475},[],[477],{"type":42,"value":478},"src\u002Fapi\u002F**",{"type":42,"value":480},") — the upgrade tool's codemods cover common patterns, but custom logic often uses APIs a breaking change renames or removes.",{"type":37,"tag":55,"props":482,"children":483},{},[484,486,492,494,500],{"type":42,"value":485},"Read the content-type schemas (",{"type":37,"tag":75,"props":487,"children":489},{"className":488},[],[490],{"type":42,"value":491},"src\u002Fapi\u002F**\u002Fcontent-types\u002F**\u002Fschema.json",{"type":42,"value":493}," and ",{"type":37,"tag":75,"props":495,"children":497},{"className":496},[],[498],{"type":42,"value":499},"src\u002Fcomponents\u002F**",{"type":42,"value":501},") for attributes affected by breaking changes — e.g. attribute types that changed, or attribute names that collide with new reserved\u002Fsystem names.",{"type":37,"tag":55,"props":503,"children":504},{},[505,507,512,513,519],{"type":42,"value":506},"Check ",{"type":37,"tag":75,"props":508,"children":510},{"className":509},[],[511],{"type":42,"value":90},{"type":42,"value":493},{"type":37,"tag":75,"props":514,"children":516},{"className":515},[],[517],{"type":42,"value":518},"config\u002Fplugins.{js,ts}",{"type":42,"value":520}," for third-party plugins whose compatibility may be affected.",{"type":37,"tag":45,"props":522,"children":523},{},[524,526,531],{"type":42,"value":525},"Use each breaking-change title as a search seed (grep for the removed\u002Frenamed API, the deprecated option, the reserved name). Report ",{"type":37,"tag":59,"props":527,"children":528},{},[529],{"type":42,"value":530},"which files match which breaking change",{"type":42,"value":532}," so the user sees exactly what the upgrade will touch versus what they'll need to fix by hand.",{"type":37,"tag":309,"props":534,"children":536},{"id":535},"report-and-gate",[537],{"type":42,"value":538},"Report and gate",{"type":37,"tag":362,"props":540,"children":541},{},[542,559],{"type":37,"tag":55,"props":543,"children":544},{},[545,550,552,557],{"type":37,"tag":59,"props":546,"children":547},{},[548],{"type":42,"value":549},"Same major (minor\u002Fpatch upgrade):",{"type":42,"value":551}," State clearly that there are ",{"type":37,"tag":59,"props":553,"children":554},{},[555],{"type":42,"value":556},"no breaking changes",{"type":42,"value":558}," — the breaking-changes database is scoped to major migrations only. You still performed the check; say so.",{"type":37,"tag":55,"props":560,"children":561},{},[562,567,569,574,576],{"type":37,"tag":59,"props":563,"children":564},{},[565],{"type":42,"value":566},"Major upgrade:",{"type":42,"value":568}," Summarize the applicable breaking changes grounded in the codebase scan above, flag which are handled by codemods versus which need manual code updates, call out any ",{"type":37,"tag":59,"props":570,"children":571},{},[572],{"type":42,"value":573},"reserved-name collisions",{"type":42,"value":575}," (these may need a database migration — see Step 7), and ",{"type":37,"tag":59,"props":577,"children":578},{},[579],{"type":42,"value":580},"stop and wait for the user's affirmative reply before proceeding — do not continue in the same turn.",{"type":37,"tag":107,"props":582,"children":584},{"id":583},"step-3-pre-flight-safety",[585],{"type":42,"value":586},"Step 3 — Pre-flight safety",{"type":37,"tag":45,"props":588,"children":589},{},[590,592,597,599,605],{"type":42,"value":591},"Remind the user to back up ",{"type":37,"tag":59,"props":593,"children":594},{},[595],{"type":42,"value":596},"codebase and database",{"type":42,"value":598}," before upgrading (default SQLite DB is ",{"type":37,"tag":75,"props":600,"children":602},{"className":601},[],[603],{"type":42,"value":604},".tmp\u002Fdata.db",{"type":42,"value":606},"). The upgrade tool also checks for a clean git working tree as an optional requirement, so a committed\u002Fclean tree eases rollback.",{"type":37,"tag":45,"props":608,"children":609},{},[610],{"type":42,"value":611},"Offer a dry run first to preview changes without modifying files:",{"type":37,"tag":150,"props":613,"children":615},{"className":152,"code":614,"language":154,"meta":155,"style":155},"npx @strapi\u002Fupgrade \u003Ctarget> --dry\n",[616],{"type":37,"tag":75,"props":617,"children":618},{"__ignoreMap":155},[619],{"type":37,"tag":161,"props":620,"children":621},{"class":163,"line":24},[622,627,632,638,643,649,654],{"type":37,"tag":161,"props":623,"children":624},{"style":167},[625],{"type":42,"value":626},"npx",{"type":37,"tag":161,"props":628,"children":629},{"style":173},[630],{"type":42,"value":631}," @strapi\u002Fupgrade",{"type":37,"tag":161,"props":633,"children":635},{"style":634},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[636],{"type":42,"value":637}," \u003C",{"type":37,"tag":161,"props":639,"children":640},{"style":173},[641],{"type":42,"value":642},"targe",{"type":37,"tag":161,"props":644,"children":646},{"style":645},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[647],{"type":42,"value":648},"t",{"type":37,"tag":161,"props":650,"children":651},{"style":634},[652],{"type":42,"value":653},">",{"type":37,"tag":161,"props":655,"children":656},{"style":173},[657],{"type":42,"value":658}," --dry\n",{"type":37,"tag":107,"props":660,"children":662},{"id":661},"step-4-check-the-running-node-version-before-running-the-tool",[663],{"type":42,"value":664},"Step 4 — Check the running Node version (before running the tool)",{"type":37,"tag":45,"props":666,"children":667},{},[668,669,674,676,681,683,688,690,695,697,703,705,710],{"type":42,"value":192},{"type":37,"tag":75,"props":670,"children":672},{"className":671},[],[673],{"type":42,"value":80},{"type":42,"value":675}," tool is itself a Node CLI: it runs under whatever Node ",{"type":37,"tag":75,"props":677,"children":679},{"className":678},[],[680],{"type":42,"value":626},{"type":42,"value":682}," is invoked with, and it declares the ",{"type":37,"tag":59,"props":684,"children":685},{},[686],{"type":42,"value":687},"same",{"type":42,"value":689}," Node requirement as the target Strapi. So the running Node — not just ",{"type":37,"tag":75,"props":691,"children":693},{"className":692},[],[694],{"type":42,"value":90},{"type":42,"value":696},"'s ",{"type":37,"tag":75,"props":698,"children":700},{"className":699},[],[701],{"type":42,"value":702},"engines",{"type":42,"value":704}," — must satisfy the target's range ",{"type":37,"tag":59,"props":706,"children":707},{},[708],{"type":42,"value":709},"before",{"type":42,"value":711}," you run the tool. If it doesn't, both the upgrade run and the subsequent app boot happen on an unsupported runtime.",{"type":37,"tag":51,"props":713,"children":714},{},[715,728,792,802],{"type":37,"tag":55,"props":716,"children":717},{},[718,720,726],{"type":42,"value":719},"Read the currently running Node version (",{"type":37,"tag":75,"props":721,"children":723},{"className":722},[],[724],{"type":42,"value":725},"node -v",{"type":42,"value":727},").",{"type":37,"tag":55,"props":729,"children":730},{},[731,733,738,740,787,790],{"type":42,"value":732},"Read the Node range the ",{"type":37,"tag":59,"props":734,"children":735},{},[736],{"type":42,"value":737},"target",{"type":42,"value":739}," Strapi supports:",{"type":37,"tag":150,"props":741,"children":743},{"className":152,"code":742,"language":154,"meta":155,"style":155},"npm view @strapi\u002Fstrapi@\u003Ctarget-x.y.z> engines\n",[744],{"type":37,"tag":75,"props":745,"children":746},{"__ignoreMap":155},[747],{"type":37,"tag":161,"props":748,"children":749},{"class":163,"line":24},[750,754,758,763,768,773,778,782],{"type":37,"tag":161,"props":751,"children":752},{"style":167},[753],{"type":42,"value":170},{"type":37,"tag":161,"props":755,"children":756},{"style":173},[757],{"type":42,"value":176},{"type":37,"tag":161,"props":759,"children":760},{"style":173},[761],{"type":42,"value":762}," @strapi\u002Fstrapi@",{"type":37,"tag":161,"props":764,"children":765},{"style":634},[766],{"type":42,"value":767},"\u003C",{"type":37,"tag":161,"props":769,"children":770},{"style":173},[771],{"type":42,"value":772},"target-x.y.",{"type":37,"tag":161,"props":774,"children":775},{"style":645},[776],{"type":42,"value":777},"z",{"type":37,"tag":161,"props":779,"children":780},{"style":634},[781],{"type":42,"value":653},{"type":37,"tag":161,"props":783,"children":784},{"style":173},[785],{"type":42,"value":786}," engines\n",{"type":37,"tag":188,"props":788,"children":789},{},[],{"type":42,"value":791},"(Cross-check against the docs' recommended Node for that major — Strapi recommends the active LTS.)",{"type":37,"tag":55,"props":793,"children":794},{},[795,800],{"type":37,"tag":59,"props":796,"children":797},{},[798],{"type":42,"value":799},"If the running Node already satisfies the target's range",{"type":42,"value":801},", continue to Step 5.",{"type":37,"tag":55,"props":803,"children":804},{},[805,810,812,817,819,825,827,833,835,841,843,849,851,857,859,865,867],{"type":37,"tag":59,"props":806,"children":807},{},[808],{"type":42,"value":809},"If it does not, Node must be upgraded before the upgrade.",{"type":42,"value":811}," How you handle this depends on whether the user has a ",{"type":37,"tag":59,"props":813,"children":814},{},[815],{"type":42,"value":816},"Node version manager",{"type":42,"value":818}," — check for one before deciding (look for ",{"type":37,"tag":75,"props":820,"children":822},{"className":821},[],[823],{"type":42,"value":824},"nvm",{"type":42,"value":826},", ",{"type":37,"tag":75,"props":828,"children":830},{"className":829},[],[831],{"type":42,"value":832},"fnm",{"type":42,"value":834},", or ",{"type":37,"tag":75,"props":836,"children":838},{"className":837},[],[839],{"type":42,"value":840},"volta",{"type":42,"value":842}," on ",{"type":37,"tag":75,"props":844,"children":846},{"className":845},[],[847],{"type":42,"value":848},"PATH",{"type":42,"value":850},", and for a ",{"type":37,"tag":75,"props":852,"children":854},{"className":853},[],[855],{"type":42,"value":856},".nvmrc",{"type":42,"value":858}," \u002F ",{"type":37,"tag":75,"props":860,"children":862},{"className":861},[],[863],{"type":42,"value":864},".node-version",{"type":42,"value":866}," \u002F Volta field in the repo):",{"type":37,"tag":362,"props":868,"children":869},{},[870,920,969,1029],{"type":37,"tag":55,"props":871,"children":872},{},[873,878,880,885,887],{"type":37,"tag":59,"props":874,"children":875},{},[876],{"type":42,"value":877},"If a version manager is present:",{"type":42,"value":879}," ",{"type":37,"tag":59,"props":881,"children":882},{},[883],{"type":42,"value":884},"prompt the user to ask whether they want you to upgrade the Node version",{"type":42,"value":886}," for them, and gate on their confirmation before any runtime change. Only if they confirm:\n",{"type":37,"tag":362,"props":888,"children":889},{},[890,902],{"type":37,"tag":55,"props":891,"children":892},{},[893,895,900],{"type":42,"value":894},"Pick a Node version ",{"type":37,"tag":59,"props":896,"children":897},{},[898],{"type":42,"value":899},"inside the target's range",{"type":42,"value":901},", preferring an LTS release the target lists.",{"type":37,"tag":55,"props":903,"children":904},{},[905,907,912,913,918],{"type":42,"value":906},"Switch via their version manager (never a global install) so the change is reversible — the old Strapi can still run on the old Node if a rollback is needed. Suggest pinning it in the repo (",{"type":37,"tag":75,"props":908,"children":910},{"className":909},[],[911],{"type":42,"value":856},{"type":42,"value":858},{"type":37,"tag":75,"props":914,"children":916},{"className":915},[],[917],{"type":42,"value":864},{"type":42,"value":919}," \u002F Volta field) so CI and teammates move together.",{"type":37,"tag":55,"props":921,"children":922},{},[923,928,930,935,937,942,944,949,950,955,956,961,962,967],{"type":37,"tag":59,"props":924,"children":925},{},[926],{"type":42,"value":927},"If no version manager is present:",{"type":42,"value":929}," do ",{"type":37,"tag":59,"props":931,"children":932},{},[933],{"type":42,"value":934},"not",{"type":42,"value":936}," attempt to change the system Node yourself — a global runtime swap is risky and not cleanly reversible. Instead, ",{"type":37,"tag":59,"props":938,"children":939},{},[940],{"type":42,"value":941},"tell the user to fix the Node version on their own",{"type":42,"value":943},", and recommend they do it by ",{"type":37,"tag":59,"props":945,"children":946},{},[947],{"type":42,"value":948},"installing a version manager first",{"type":42,"value":127},{"type":37,"tag":75,"props":951,"children":953},{"className":952},[],[954],{"type":42,"value":824},{"type":42,"value":826},{"type":37,"tag":75,"props":957,"children":959},{"className":958},[],[960],{"type":42,"value":832},{"type":42,"value":834},{"type":37,"tag":75,"props":963,"children":965},{"className":964},[],[966],{"type":42,"value":840},{"type":42,"value":968},"), then selecting a Node version inside the target's range. Stop and wait for them to sort the runtime out before continuing.",{"type":37,"tag":55,"props":970,"children":971},{},[972,985,987,992,994,999,1001,1006,1008,1013,1015,1020,1022,1027],{"type":37,"tag":59,"props":973,"children":974},{},[975,977,983],{"type":42,"value":976},"Do not reinstall ",{"type":37,"tag":75,"props":978,"children":980},{"className":979},[],[981],{"type":42,"value":982},"node_modules",{"type":42,"value":984}," immediately after switching Node.",{"type":42,"value":986}," At that point ",{"type":37,"tag":75,"props":988,"children":990},{"className":989},[],[991],{"type":42,"value":90},{"type":42,"value":993}," still pins the ",{"type":37,"tag":59,"props":995,"children":996},{},[997],{"type":42,"value":998},"old",{"type":42,"value":1000}," Strapi, so a clean install would rebuild the ",{"type":37,"tag":1002,"props":1003,"children":1004},"em",{},[1005],{"type":42,"value":998},{"type":42,"value":1007}," dependency tree against the new Node — which, if the ranges are disjoint (below), can fail the ",{"type":37,"tag":75,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":42,"value":702},{"type":42,"value":1014}," check or leave native modules built against the wrong ABI, breaking the working state before the tool has moved you forward. The clean reinstall belongs ",{"type":37,"tag":59,"props":1016,"children":1017},{},[1018],{"type":42,"value":1019},"after",{"type":42,"value":1021}," Step 5, once the tool has rewritten ",{"type":37,"tag":75,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":42,"value":90},{"type":42,"value":1028}," to the target (see Step 7d).",{"type":37,"tag":55,"props":1030,"children":1031},{},[1032,1037,1039,1043,1045,1050,1052,1058,1060,1065,1067,1071],{"type":37,"tag":59,"props":1033,"children":1034},{},[1035],{"type":42,"value":1036},"When the current and target Node ranges do not overlap at all",{"type":42,"value":1038}," (e.g. current supports Node 18, target requires ≥20), a clean in-place swap isn't possible while staying on the old runtime. The safe ordering is: on the ",{"type":37,"tag":59,"props":1040,"children":1041},{},[1042],{"type":42,"value":998},{"type":42,"value":1044}," Node, first get the current major to its ",{"type":37,"tag":59,"props":1046,"children":1047},{},[1048],{"type":42,"value":1049},"latest patch",{"type":42,"value":1051}," (run ",{"type":37,"tag":75,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":42,"value":1057},"npx @strapi\u002Fupgrade minor",{"type":42,"value":1059},"), so that step stays rollback-able; ",{"type":37,"tag":1002,"props":1061,"children":1062},{},[1063],{"type":42,"value":1064},"then",{"type":42,"value":1066}," switch Node into the target's range; ",{"type":37,"tag":1002,"props":1068,"children":1069},{},[1070],{"type":42,"value":1064},{"type":42,"value":1072}," run the major upgrade in Step 5. Only after that upgrade run do you reinstall dependencies.",{"type":37,"tag":107,"props":1074,"children":1076},{"id":1075},"step-5-run-the-upgrade-with-the-upgrade-tool",[1077],{"type":42,"value":1078},"Step 5 — Run the upgrade with the upgrade tool",{"type":37,"tag":45,"props":1080,"children":1081},{},[1082],{"type":42,"value":1083},"Run the official tool from the project root. Choose the command form that matches the target:",{"type":37,"tag":150,"props":1085,"children":1087},{"className":152,"code":1086,"language":154,"meta":155,"style":155},"npx @strapi\u002Fupgrade latest          # newest stable version\nnpx @strapi\u002Fupgrade major           # next major (requires being on latest patch of current major first)\nnpx @strapi\u002Fupgrade minor           # latest minor+patch in current major\nnpx @strapi\u002Fupgrade patch           # latest patch in current minor\nnpx @strapi\u002Fupgrade to \u003Cx.y.z>      # a specific published version\n",[1088],{"type":37,"tag":75,"props":1089,"children":1090},{"__ignoreMap":155},[1091,1113,1134,1156,1178],{"type":37,"tag":161,"props":1092,"children":1093},{"class":163,"line":24},[1094,1098,1102,1107],{"type":37,"tag":161,"props":1095,"children":1096},{"style":167},[1097],{"type":42,"value":626},{"type":37,"tag":161,"props":1099,"children":1100},{"style":173},[1101],{"type":42,"value":631},{"type":37,"tag":161,"props":1103,"children":1104},{"style":173},[1105],{"type":42,"value":1106}," latest",{"type":37,"tag":161,"props":1108,"children":1110},{"style":1109},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1111],{"type":42,"value":1112},"          # newest stable version\n",{"type":37,"tag":161,"props":1114,"children":1115},{"class":163,"line":20},[1116,1120,1124,1129],{"type":37,"tag":161,"props":1117,"children":1118},{"style":167},[1119],{"type":42,"value":626},{"type":37,"tag":161,"props":1121,"children":1122},{"style":173},[1123],{"type":42,"value":631},{"type":37,"tag":161,"props":1125,"children":1126},{"style":173},[1127],{"type":42,"value":1128}," major",{"type":37,"tag":161,"props":1130,"children":1131},{"style":1109},[1132],{"type":42,"value":1133},"           # next major (requires being on latest patch of current major first)\n",{"type":37,"tag":161,"props":1135,"children":1137},{"class":163,"line":1136},3,[1138,1142,1146,1151],{"type":37,"tag":161,"props":1139,"children":1140},{"style":167},[1141],{"type":42,"value":626},{"type":37,"tag":161,"props":1143,"children":1144},{"style":173},[1145],{"type":42,"value":631},{"type":37,"tag":161,"props":1147,"children":1148},{"style":173},[1149],{"type":42,"value":1150}," minor",{"type":37,"tag":161,"props":1152,"children":1153},{"style":1109},[1154],{"type":42,"value":1155},"           # latest minor+patch in current major\n",{"type":37,"tag":161,"props":1157,"children":1159},{"class":163,"line":1158},4,[1160,1164,1168,1173],{"type":37,"tag":161,"props":1161,"children":1162},{"style":167},[1163],{"type":42,"value":626},{"type":37,"tag":161,"props":1165,"children":1166},{"style":173},[1167],{"type":42,"value":631},{"type":37,"tag":161,"props":1169,"children":1170},{"style":173},[1171],{"type":42,"value":1172}," patch",{"type":37,"tag":161,"props":1174,"children":1175},{"style":1109},[1176],{"type":42,"value":1177},"           # latest patch in current minor\n",{"type":37,"tag":161,"props":1179,"children":1181},{"class":163,"line":1180},5,[1182,1186,1190,1195,1199,1204,1208,1212],{"type":37,"tag":161,"props":1183,"children":1184},{"style":167},[1185],{"type":42,"value":626},{"type":37,"tag":161,"props":1187,"children":1188},{"style":173},[1189],{"type":42,"value":631},{"type":37,"tag":161,"props":1191,"children":1192},{"style":173},[1193],{"type":42,"value":1194}," to",{"type":37,"tag":161,"props":1196,"children":1197},{"style":634},[1198],{"type":42,"value":637},{"type":37,"tag":161,"props":1200,"children":1201},{"style":173},[1202],{"type":42,"value":1203},"x.y.",{"type":37,"tag":161,"props":1205,"children":1206},{"style":645},[1207],{"type":42,"value":777},{"type":37,"tag":161,"props":1209,"children":1210},{"style":634},[1211],{"type":42,"value":653},{"type":37,"tag":161,"props":1213,"children":1214},{"style":1109},[1215],{"type":42,"value":1216},"      # a specific published version\n",{"type":37,"tag":45,"props":1218,"children":1219},{},[1220],{"type":42,"value":1221},"Notes:",{"type":37,"tag":362,"props":1223,"children":1224},{},[1225,1249,1292,1304],{"type":37,"tag":55,"props":1226,"children":1227},{},[1228,1233,1235,1240,1242,1247],{"type":37,"tag":75,"props":1229,"children":1231},{"className":1230},[],[1232],{"type":42,"value":219},{"type":42,"value":1234}," is gated: the project must already be on the latest patch of its current major. If it isn't, run ",{"type":37,"tag":75,"props":1236,"children":1238},{"className":1237},[],[1239],{"type":42,"value":227},{"type":42,"value":1241}," first, then ",{"type":37,"tag":75,"props":1243,"children":1245},{"className":1244},[],[1246],{"type":42,"value":219},{"type":42,"value":1248},".",{"type":37,"tag":55,"props":1250,"children":1251},{},[1252,1253,1259,1261,1266,1268,1274,1276,1282,1284,1290],{"type":42,"value":380},{"type":37,"tag":75,"props":1254,"children":1256},{"className":1255},[],[1257],{"type":42,"value":1258},"to \u003Cx.y.z>",{"type":42,"value":1260}," when ",{"type":37,"tag":75,"props":1262,"children":1264},{"className":1263},[],[1265],{"type":42,"value":198},{"type":42,"value":1267}," is blocked by a registry policy (e.g. ",{"type":37,"tag":75,"props":1269,"children":1271},{"className":1270},[],[1272],{"type":42,"value":1273},"min-release-age",{"type":42,"value":1275}," in ",{"type":37,"tag":75,"props":1277,"children":1279},{"className":1278},[],[1280],{"type":42,"value":1281},".npmrc",{"type":42,"value":1283},") or when the user wants an exact version. ",{"type":37,"tag":75,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":42,"value":1289},"to",{"type":42,"value":1291}," skips the major-safety check intentionally.",{"type":37,"tag":55,"props":1293,"children":1294},{},[1295,1297,1303],{"type":42,"value":1296},"For pre-releases, add ",{"type":37,"tag":75,"props":1298,"children":1300},{"className":1299},[],[1301],{"type":42,"value":1302},"--codemods-target \u003Cx.y.z>",{"type":42,"value":1248},{"type":37,"tag":55,"props":1305,"children":1306},{},[1307,1309,1315,1317,1323,1325,1331,1333,1345,1347,1352,1354,1359],{"type":42,"value":1308},"Useful flags: ",{"type":37,"tag":75,"props":1310,"children":1312},{"className":1311},[],[1313],{"type":42,"value":1314},"-y\u002F--yes",{"type":42,"value":1316}," (auto-confirm prompts), ",{"type":37,"tag":75,"props":1318,"children":1320},{"className":1319},[],[1321],{"type":42,"value":1322},"-d\u002F--debug",{"type":42,"value":1324}," (verbose), ",{"type":37,"tag":75,"props":1326,"children":1328},{"className":1327},[],[1329],{"type":42,"value":1330},"-p\u002F--project-path \u003Cpath>",{"type":42,"value":1332}," (non-cwd project). ",{"type":37,"tag":59,"props":1334,"children":1335},{},[1336,1338,1343],{"type":42,"value":1337},"Avoid ",{"type":37,"tag":75,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":42,"value":1314},{"type":42,"value":1344}," for major jumps",{"type":42,"value":1346}," — it auto-confirms ",{"type":37,"tag":1002,"props":1348,"children":1349},{},[1350],{"type":42,"value":1351},"every",{"type":42,"value":1353}," prompt, including the major-version safety prompt on ",{"type":37,"tag":75,"props":1355,"children":1357},{"className":1356},[],[1358],{"type":42,"value":198},{"type":42,"value":1360},". Prefer interactive mode (or explicit per-step user approval) unless the user asked for an unattended run.",{"type":37,"tag":45,"props":1362,"children":1363},{},[1364,1366,1371,1373,1378,1380,1386],{"type":42,"value":1365},"The tool updates dependencies, installs them, and runs codemods for the target version. ",{"type":37,"tag":59,"props":1367,"children":1368},{},[1369],{"type":42,"value":1370},"Do not",{"type":42,"value":1372}," substitute a manual ",{"type":37,"tag":75,"props":1374,"children":1376},{"className":1375},[],[1377],{"type":42,"value":90},{"type":42,"value":1379}," edit or a bare ",{"type":37,"tag":75,"props":1381,"children":1383},{"className":1382},[],[1384],{"type":42,"value":1385},"npm install",{"type":42,"value":1387}," for this step.",{"type":37,"tag":45,"props":1389,"children":1390},{},[1391,1393,1399,1401,1413,1414,1420],{"type":42,"value":1392},"If the install phase fails (e.g. ",{"type":37,"tag":75,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":42,"value":1398},"ERESOLVE",{"type":42,"value":1400},"), first retry with a ",{"type":37,"tag":59,"props":1402,"children":1403},{},[1404,1406,1411],{"type":42,"value":1405},"clean ",{"type":37,"tag":75,"props":1407,"children":1409},{"className":1408},[],[1410],{"type":42,"value":982},{"type":42,"value":1412}," and lockfile",{"type":42,"value":127},{"type":37,"tag":75,"props":1415,"children":1417},{"className":1416},[],[1418],{"type":42,"value":1419},"rm -rf node_modules package-lock.json && npm install",{"type":42,"value":1421},") before falling back to any manual dependency edits — a stale lockfile from the old major is the most common cause and a clean reinstall usually resolves it.",{"type":37,"tag":107,"props":1423,"children":1425},{"id":1424},"step-6-fix-the-engines-field",[1426,1428,1433],{"type":42,"value":1427},"Step 6 — Fix the ",{"type":37,"tag":75,"props":1429,"children":1431},{"className":1430},[],[1432],{"type":42,"value":702},{"type":42,"value":1434}," field",{"type":37,"tag":45,"props":1436,"children":1437},{},[1438,1440,1457,1459,1465,1467,1478,1479,1484,1485,1491,1492,1498,1500,1505,1507,1512],{"type":42,"value":1439},"The upgrade tool updates dependencies but ",{"type":37,"tag":59,"props":1441,"children":1442},{},[1443,1445,1450,1451,1456],{"type":42,"value":1444},"does not touch ",{"type":37,"tag":75,"props":1446,"children":1448},{"className":1447},[],[1449],{"type":42,"value":90},{"type":42,"value":696},{"type":37,"tag":75,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":42,"value":702},{"type":42,"value":1434},{"type":42,"value":1458},". A stale ",{"type":37,"tag":75,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":42,"value":1464},"engines.node",{"type":42,"value":1466}," range left over from the old major can fail the compatibility check and ",{"type":37,"tag":59,"props":1468,"children":1469},{},[1470,1472],{"type":42,"value":1471},"block ",{"type":37,"tag":75,"props":1473,"children":1475},{"className":1474},[],[1476],{"type":42,"value":1477},"install",{"type":42,"value":127},{"type":37,"tag":75,"props":1480,"children":1482},{"className":1481},[],[1483],{"type":42,"value":170},{"type":42,"value":221},{"type":37,"tag":75,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":42,"value":1490},"yarn",{"type":42,"value":221},{"type":37,"tag":75,"props":1493,"children":1495},{"className":1494},[],[1496],{"type":42,"value":1497},"pnpm",{"type":42,"value":1499},") after the upgrade. (This is the declared range in ",{"type":37,"tag":75,"props":1501,"children":1503},{"className":1502},[],[1504],{"type":42,"value":90},{"type":42,"value":1506}," — distinct from the ",{"type":37,"tag":1002,"props":1508,"children":1509},{},[1510],{"type":42,"value":1511},"running",{"type":42,"value":1513}," Node you checked in Step 4.)",{"type":37,"tag":51,"props":1515,"children":1516},{},[1517,1534,1546],{"type":37,"tag":55,"props":1518,"children":1519},{},[1520,1521,1526,1528,1533],{"type":42,"value":444},{"type":37,"tag":75,"props":1522,"children":1524},{"className":1523},[],[1525],{"type":42,"value":702},{"type":42,"value":1527}," from the project's ",{"type":37,"tag":75,"props":1529,"children":1531},{"className":1530},[],[1532],{"type":42,"value":90},{"type":42,"value":1248},{"type":37,"tag":55,"props":1535,"children":1536},{},[1537,1539,1545],{"type":42,"value":1538},"Reuse the target's Node range from Step 4 (",{"type":37,"tag":75,"props":1540,"children":1542},{"className":1541},[],[1543],{"type":42,"value":1544},"npm view @strapi\u002Fstrapi@\u003Ctarget-x.y.z> engines",{"type":42,"value":727},{"type":37,"tag":55,"props":1547,"children":1548},{},[1549,1551,1556,1558,1563],{"type":42,"value":1550},"If the project's ",{"type":37,"tag":75,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":42,"value":1464},{"type":42,"value":1557}," is narrower than or incompatible with the target's, ",{"type":37,"tag":59,"props":1559,"children":1560},{},[1561],{"type":42,"value":1562},"offer to replace it",{"type":42,"value":1564}," with the correct range for the target major, and apply the edit once the user confirms. Leave it alone if it's already compatible.",{"type":37,"tag":107,"props":1566,"children":1568},{"id":1567},"step-7-post-upgrade-codemod-gaps-plugins-migrations",[1569],{"type":42,"value":1570},"Step 7 — Post-upgrade: codemod gaps, plugins, migrations",{"type":37,"tag":45,"props":1572,"children":1573},{},[1574,1576,1581],{"type":42,"value":1575},"Run these in order. Each destructive or code-changing action ",{"type":37,"tag":59,"props":1577,"children":1578},{},[1579],{"type":42,"value":1580},"pauses for the user to confirm",{"type":42,"value":1582}," — the user is in charge of every change beyond what the tool applied automatically.",{"type":37,"tag":309,"props":1584,"children":1586},{"id":1585},"_7a-review-and-offer-to-fix-the-codemod-gaps",[1587],{"type":42,"value":1588},"7a — Review and offer to fix the codemod gaps",{"type":37,"tag":51,"props":1590,"children":1591},{},[1592,1611],{"type":37,"tag":55,"props":1593,"children":1594},{},[1595,1597,1602,1604,1609],{"type":42,"value":1596},"Tell the user to ",{"type":37,"tag":59,"props":1598,"children":1599},{},[1600],{"type":42,"value":1601},"review the changes",{"type":42,"value":1603}," the tool made (especially codemod edits and ",{"type":37,"tag":75,"props":1605,"children":1607},{"className":1606},[],[1608],{"type":42,"value":90},{"type":42,"value":1610},") before restarting the app.",{"type":37,"tag":55,"props":1612,"children":1613},{},[1614,1616,1621,1623,1628,1630,1634],{"type":42,"value":1615},"Codemods cover common patterns, not everything. Cross-reference the breaking changes flagged as \"manual\" in Step 2 against the code the codemods actually changed. For anything still unhandled, ",{"type":37,"tag":59,"props":1617,"children":1618},{},[1619],{"type":42,"value":1620},"ask the user whether they want you to attempt the fixes",{"type":42,"value":1622}," in application code — then ",{"type":37,"tag":59,"props":1624,"children":1625},{},[1626],{"type":42,"value":1627},"wait for their affirmative reply; do not start editing in the same turn.",{"type":42,"value":1629}," Only edit code after they confirm, and edit ",{"type":37,"tag":1002,"props":1631,"children":1632},{},[1633],{"type":42,"value":1019},{"type":42,"value":1635}," the tool's codemods have been applied (never before — you'd fight the codemods).",{"type":37,"tag":309,"props":1637,"children":1639},{"id":1638},"_7b-upgrade-incompatible-third-party-plugins",[1640],{"type":42,"value":1641},"7b — Upgrade incompatible third-party plugins",{"type":37,"tag":45,"props":1643,"children":1644},{},[1645,1647,1652,1653,1659,1661,1666],{"type":42,"value":1646},"If any third-party plugin (from Step 2's ",{"type":37,"tag":75,"props":1648,"children":1650},{"className":1649},[],[1651],{"type":42,"value":90},{"type":42,"value":221},{"type":37,"tag":75,"props":1654,"children":1656},{"className":1655},[],[1657],{"type":42,"value":1658},"config\u002Fplugins",{"type":42,"value":1660}," scan, or surfaced by install\u002Fboot errors) is ",{"type":37,"tag":59,"props":1662,"children":1663},{},[1664],{"type":42,"value":1665},"not compatible",{"type":42,"value":1667}," with the target Strapi version:",{"type":37,"tag":51,"props":1669,"children":1670},{},[1671,1690,1700],{"type":37,"tag":55,"props":1672,"children":1673},{},[1674,1676,1682,1684,1689],{"type":42,"value":1675},"Identify a plugin version that supports the target (",{"type":37,"tag":75,"props":1677,"children":1679},{"className":1678},[],[1680],{"type":42,"value":1681},"npm view \u003Cplugin> versions",{"type":42,"value":1683}," \u002F its peer-dependency range on ",{"type":37,"tag":75,"props":1685,"children":1687},{"className":1686},[],[1688],{"type":42,"value":133},{"type":42,"value":727},{"type":37,"tag":55,"props":1691,"children":1692},{},[1693,1698],{"type":37,"tag":59,"props":1694,"children":1695},{},[1696],{"type":42,"value":1697},"Ask the user before upgrading each plugin individually",{"type":42,"value":1699}," — confirm every plugin bump separately; never batch-upgrade plugins silently.",{"type":37,"tag":55,"props":1701,"children":1702},{},[1703],{"type":42,"value":1704},"Apply the confirmed version bump and reinstall.",{"type":37,"tag":309,"props":1706,"children":1708},{"id":1707},"_7c-reserved-name-collisions-custom-database-migration",[1709],{"type":42,"value":1710},"7c — Reserved-name collisions → custom database migration",{"type":37,"tag":45,"props":1712,"children":1713},{},[1714,1716,1721],{"type":42,"value":1715},"If Step 2 found an attribute whose name collides with a new ",{"type":37,"tag":59,"props":1717,"children":1718},{},[1719],{"type":42,"value":1720},"reserved\u002Fsystem name",{"type":42,"value":1722}," in the target major, a rename is required and renaming a column risks data loss. In that case:",{"type":37,"tag":51,"props":1724,"children":1725},{},[1726,1736,1748,1772],{"type":37,"tag":55,"props":1727,"children":1728},{},[1729,1734],{"type":37,"tag":59,"props":1730,"children":1731},{},[1732],{"type":42,"value":1733},"Ask the user whether to proceed with the rename",{"type":42,"value":1735}," at all.",{"type":37,"tag":55,"props":1737,"children":1738},{},[1739,1741,1746],{"type":42,"value":1740},"If yes, ",{"type":37,"tag":59,"props":1742,"children":1743},{},[1744],{"type":42,"value":1745},"ask whether you should generate a database migration",{"type":42,"value":1747}," to preserve existing data during the rename.",{"type":37,"tag":55,"props":1749,"children":1750},{},[1751,1756,1758,1763,1765,1770],{"type":37,"tag":59,"props":1752,"children":1753},{},[1754],{"type":42,"value":1755},"Require an explicit backup confirmation before writing or running any migration.",{"type":42,"value":1757}," The migration executes against the real database on next boot and the rename is not cleanly reversible, so ask the user to confirm ",{"type":37,"tag":59,"props":1759,"children":1760},{},[1761],{"type":42,"value":1762},"they have manually backed up the database",{"type":42,"value":1764}," — then ",{"type":37,"tag":59,"props":1766,"children":1767},{},[1768],{"type":42,"value":1769},"stop and wait for a clear \"yes\" in a separate reply; do not continue in the same turn.",{"type":42,"value":1771}," Do not proceed on a vague answer, and never take the backup on their behalf as a substitute for their confirmation. If they have not backed up, stop and let them do it first.",{"type":37,"tag":55,"props":1773,"children":1774},{},[1775,1777,1785,1787,1793],{"type":42,"value":1776},"Only after that confirmation, author the migration following ",{"type":37,"tag":59,"props":1778,"children":1779},{},[1780],{"type":37,"tag":264,"props":1781,"children":1783},{"href":1782},"reference.md",[1784],{"type":42,"value":1782},{"type":42,"value":1786}," (placement, ordering gotchas, data-safe rename, system-column collisions, idempotency, ",{"type":37,"tag":75,"props":1788,"children":1790},{"className":1789},[],[1791],{"type":42,"value":1792},"down()",{"type":42,"value":1794},"). Do not hand-wave this — the ordering and collision rules there prevent both boot failures and silent data loss.",{"type":37,"tag":309,"props":1796,"children":1798},{"id":1797},"_7d-verify",[1799],{"type":42,"value":1800},"7d — Verify",{"type":37,"tag":51,"props":1802,"children":1803},{},[1804,1823,1863],{"type":37,"tag":55,"props":1805,"children":1806},{},[1807,1809,1813,1815,1821],{"type":42,"value":1808},"For major upgrades, note that Strapi's built-in data migrations run automatically on first startup in the new major — the upgrade tool does ",{"type":37,"tag":59,"props":1810,"children":1811},{},[1812],{"type":42,"value":934},{"type":42,"value":1814}," migrate data itself, and any custom migration in ",{"type":37,"tag":75,"props":1816,"children":1818},{"className":1817},[],[1819],{"type":42,"value":1820},".\u002Fdatabase\u002Fmigrations\u002F",{"type":42,"value":1822}," also runs then.",{"type":37,"tag":55,"props":1824,"children":1825},{},[1826,1831,1833,1838,1840,1846,1848,1854,1855,1861],{"type":37,"tag":59,"props":1827,"children":1828},{},[1829],{"type":42,"value":1830},"If Node was switched in Step 4, do a clean reinstall now",{"type":42,"value":1832}," — after the tool has rewritten ",{"type":37,"tag":75,"props":1834,"children":1836},{"className":1835},[],[1837],{"type":42,"value":90},{"type":42,"value":1839}," to the target, not before: ",{"type":37,"tag":75,"props":1841,"children":1843},{"className":1842},[],[1844],{"type":42,"value":1845},"rm -rf node_modules && install",{"type":42,"value":1847},". Native modules (",{"type":37,"tag":75,"props":1849,"children":1851},{"className":1850},[],[1852],{"type":42,"value":1853},"better-sqlite3",{"type":42,"value":826},{"type":37,"tag":75,"props":1856,"children":1858},{"className":1857},[],[1859],{"type":42,"value":1860},"sharp",{"type":42,"value":1862},", …) are compiled against a specific Node ABI; a stale build left over from the old Node is the most common \"changed Node and it won't boot\" failure and is easily misread as an upgrade bug.",{"type":37,"tag":55,"props":1864,"children":1865},{},[1866],{"type":42,"value":1867},"Verify: reinstall if needed, rebuild the admin, and start the app to confirm it boots cleanly.",{"type":37,"tag":1869,"props":1870,"children":1871},"style",{},[1872],{"type":42,"value":1873},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1875,"total":1136},[1876,1890,1905],{"slug":297,"name":297,"fn":1877,"description":1878,"org":1879,"tags":1880,"stars":20,"repoUrl":21,"updatedAt":1889},"search Strapi documentation","Query the official Strapi documentation through the strapi-docs MCP server (powered by Kapa). Use for any Strapi question — API syntax, configuration, features, plugins, upgrades, CLI. If the server is missing, instruct the user how to install it.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1881,1882,1885,1888],{"name":15,"slug":16,"type":13},{"name":1883,"slug":1884,"type":13},"Documentation","documentation",{"name":1886,"slug":1887,"type":13},"Reference","reference",{"name":9,"slug":8,"type":13},"2026-07-16T06:00:16.355045",{"slug":1891,"name":1891,"fn":1892,"description":1893,"org":1894,"tags":1895,"stars":20,"repoUrl":21,"updatedAt":1904},"strapi-mcp-capabilities","create custom MCP capabilities for Strapi","Create custom MCP capabilities (tools, prompts, resources) in a Strapi 5 plugin via the strapi.ai.mcp service. Use when adding a custom MCP tool\u002Fprompt\u002Fresource to Strapi, extending the Strapi MCP server.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1896,1897,1900,1903],{"name":15,"slug":16,"type":13},{"name":1898,"slug":1899,"type":13},"MCP","mcp",{"name":1901,"slug":1902,"type":13},"Plugin Development","plugin-development",{"name":9,"slug":8,"type":13},"2026-07-16T06:03:02.629114",{"slug":4,"name":4,"fn":5,"description":6,"org":1906,"tags":1907,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1908,1909,1910],{"name":15,"slug":16,"type":13},{"name":18,"slug":19,"type":13},{"name":9,"slug":8,"type":13},{"items":1912,"total":1136},[1913,1920,1927],{"slug":297,"name":297,"fn":1877,"description":1878,"org":1914,"tags":1915,"stars":20,"repoUrl":21,"updatedAt":1889},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1916,1917,1918,1919],{"name":15,"slug":16,"type":13},{"name":1883,"slug":1884,"type":13},{"name":1886,"slug":1887,"type":13},{"name":9,"slug":8,"type":13},{"slug":1891,"name":1891,"fn":1892,"description":1893,"org":1921,"tags":1922,"stars":20,"repoUrl":21,"updatedAt":1904},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1923,1924,1925,1926],{"name":15,"slug":16,"type":13},{"name":1898,"slug":1899,"type":13},{"name":1901,"slug":1902,"type":13},{"name":9,"slug":8,"type":13},{"slug":4,"name":4,"fn":5,"description":6,"org":1928,"tags":1929,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1930,1931,1932],{"name":15,"slug":16,"type":13},{"name":18,"slug":19,"type":13},{"name":9,"slug":8,"type":13}]