users-permissions: move server code into server/src (#26105)
π Enhancement
content-type-builder: support required on relation attributes (#27080)
core: look models up on the registries in getModel (#27143)
database: reduce per-column work when mapping rows to entities (#27144)
β οΈ Changes to be aware of
Filter operators: literal wildcards and true case-insensitive equality
$eqi / $nei now do real case-insensitive equality (= LOWER(?)), not LIKE, so values with %, _, or a trailing \ no longer act as wildcards or crash some databases. Substring operators ($contains, $startsWith, $endsWith, and case-insensitive variants) now treat %, _, and \ in the filter value as literal characters. If you relied on % / _ inside those filters as SQL wildcards, update filters to match the new literal semantics.
(#26476)
deps: upgrade handlebars, axios, tar, and related transitive deps (#27091)
deps: bump @radix-ui/react-toolbar from 1.0.4 to 1.1.11 (#27059)
email-nodemailer: migrate unit tests from jest to vitest (#27074)
email-sendmail: migrate unit tests from jest to vitest (#27075)
upload-local: migrate unit tests from jest to vitest (#27073)
β οΈ Changes to be aware of
Required media and relations: opt-in strictRelations
New config api.documents.strictRelations enforces required media and relations on publish (drafts can still be empty). On by default for new projects; existing apps are unchanged until you set it. To opt in, set documents.strictRelations: true in config/api.
(#27028)
Empty multiple media / morphMany now returns []
Populated empty morphMany relations (including type: 'media', multiple: true) serialize as [] instead of null, matching other to-many relations. This is unconditional and not gated by strictRelations. If clients, webhooks, or integrations check field === null for empty galleries / morphMany, treat [] as empty instead (e.g. !field?.length).
(#27090)
typescript-utils: bump internal deps to 5.50.1 (#26946)
β οΈ Changes to be aware of
Admin auth cookie name
You can set admin.auth.cookie.name in admin config to rename the access-token cookie (default remains jwtToken). Useful when another app on a shared parent domain sets a jwtToken cookie and breaks admin login.
In v5, status is reserved for draft/published filtering. If a content type has Draft & Publish enabled and a custom status field, Strapi now logs a startup warning instead of failing boot. The Content-Type Builder still blocks adding status or enabling D&P when status already exists.
@strapi/upgrade now warns and offers to pin ranged @strapi/* dependencies (e.g. ^5.50.0) before upgrading, so upgrades don't silently report "already up-to-date" when node_modules resolved ahead of package.json.
Save a draft with Cmd/Ctrl+Enter (or Cmd/Ctrl+S). Publish with Cmd/Ctrl+Shift+Enter. Since v5.31.3, plain Cmd/Ctrl+Enter published immediately β that shortcut now saves instead. (#26621)
Content types with attributes named filters, sort, fields, or populate no longer cause 400 validation errors on populate queries and countDraftRelations (#21338, #25762)
check devDependencies when resolving required admin deps (#22130)