Directus v12.3.0stable Released Aug 18, 2026
⚠️ Breaking Change Impact Score: 7/10

Directus v12.3.0 — Release Notes & Engineering Impact

Source available — automated, not human-reviewed

Component: directus · Channel: stable. Automated analysis, not a compatibility certification. How this works.

Analysis updated: 2026-11-01.

Breaking-change evidence from the source

  • ⚠️ Potential Breaking Changes **Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076))**
  • - Fixed WebSocket rate limiting breaking on shared Redis setups where keys must start with a per-project prefix. The WebSocket limiter now accepts `RATE_LIMITER_WEBSOCKETS_*` values as overrides, including `RATE_LIMITER_WEBSOCKETS_KEY_PREFIX` to override the Redis key prefix. ([#28107](https://github.com/directus/directus/pull/28107) by @AlexGaillard)
Read the original context ↗
Source flags breaking changes — review applicability
📄 .MD
⚡ Executive Summary (TL;DR)

Directus v12.3.0. Source highlight: ⚠️ Potential Breaking Changes

Who Does This Impact? (Role-Based Analysis)

💻 Software Engineers & Devs

Check the source notes against the package and APIs you use before upgrading.

📊 Product & Engineering Leads

Use the documented changes to assess relevance to your product; release frequency alone is not a quality measure.

⚙️ DevOps & Security

Verify the target version, runtime requirements and rollback procedure in the official documentation.

⚠️ Breaking Changes & Deprecations (2)

  • ⚠️ Potential Breaking Changes **Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076))**
  • - Fixed WebSocket rate limiting breaking on shared Redis setups where keys must start with a per-project prefix. The WebSocket limiter now accepts `RATE_LIMITER_WEBSOCKETS_*` values as overrides, including `RATE_LIMITER_WEBSOCKETS_KEY_PREFIX` to override the Redis key prefix. ([#28107](https://github.com/directus/directus/pull/28107) by @AlexGaillard)

✨ New Features & Capabilities (6)

  • Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. (#27797 by @bryantgillespie)
  • Added a caption field to the WYSIWYG image drawer, which wraps the image in a `figure` with a `figcaption` (#28026 by @alvarosabu)
  • Added the collection name appended to display template in item and drawer headers (#28078 by @AlexGaillard)
  • Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. (#27797 by @bryantgillespie)
  • Introduced `@directus/cli` (`d6s` / `directus-cli`) — a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files, with `sync pull`, `sync diff`, `sync push`, and an interactive wizard (#27861 by @bryantgillespie)
  • Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` (#27945 by @kheiner)

🔧 Bug Fixes & Patches (6)

  • Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query (#27759 by @ComfortablyCoding)
  • Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
  • Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
  • Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
  • Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
  • Removed unused dependencies across the monorepo (#28049 by @ComfortablyCoding)
📄 View Raw Release Notes (Original Developer Log)
### ⚠️ Potential Breaking Changes **Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076))** `exists()` now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of also reporting `false`. Callers that relied on a `false` result for any failure need to handle the error. Note that S3 answers 403 rather than 404 for a missing object when the credentials cannot list the bucket, so granting `s3:ListBucket` is needed to keep getting a clean "missing" answer. **Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759))** **Nothing to target is a no-op** "Update Items" and "Delete Items" operations now return `null` instead of falling back to every item whenever the configuration doesn't target anything — that is, when `key` is empty or missing (e.g. `[]`, `""`) and `query` is empty or missing (e.g. `{}`). "Update Items" additionally returns `null` when there is nothing to write, i.e. an empty or missing `payload` (e.g. `{}`, or `[]` for a batch payload). Flows that relied on the previous fallback to every item can use `{"limit": -1}`. **Contradictory options error** "Update Items" and "Delete Items" operations now throw an error when both `key` and `query` are defined. "Update Items" also throws when `key` or `query` is combined with a batch payload. **Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111))** The default maximum output dimension is now `6000` px. Users who rely on the previous limit of `3000` px can explicitly configure `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION`. **Used the `pm2` bundled with `@directus/api` in the Docker images instead of installing a separate copy, so its dependencies follow the versions pinned by the workspace ([#28120](https://github.com/directus/directus/pull/28120))** If you extend the Docker image: it now boots via `CMD ["node", "docker-entrypoint.cjs"]`, which runs the same `bootstrap` then `pm2-runtime` sequence as before. `pm2-runtime` is no longer on the `PATH`, so a custom `CMD` that called it directly should hand off to `docker-entrypoint.cjs` instead. `pm2` itself remains on the `PATH` for `docker exec` diagnostics. - **@directus/api** - Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query ([#27759](https://github.com/directus/directus/pull/27759) by @ComfortablyCoding) - **@directus/storage-driver-cloudinary** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-s3** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-local** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-supabase** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/sdk** - Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner) ### ✨ New Features & Improvements - **@directus/app** - Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. ([#27797](https://github.com/directus/directus/pull/27797) by @bryantgillespie) - Added a caption field to the WYSIWYG image drawer, which wraps the image in a `figure` with a `figcaption` ([#28026](https://github.com/directus/directus/pull/28026) by @alvarosabu) - Added the collection name appended to display template in item and drawer headers ([#28078](https://github.com/directus/directus/pull/28078) by @AlexGaillard) - **@directus/api** - Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. ([#27797](https://github.com/directus/directus/pull/27797) by @bryantgillespie) - **@directus/cli** - Introduced `@directus/cli` (`d6s` / `directus-cli`) — a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files, with `sync pull`, `sync diff`, `sync push`, and an interactive wizard ([#27861](https://github.com/directus/directus/pull/27861) by @bryantgillespie) - **@directus/types** - Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner) ### 🐛 Bug Fixes & Optimizations - **@directus/app** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - Removed dead “Save and Quit” dropdown row outside the content item view ([#28051](https://github.com/directus/directus/pull/28051) by @robluton) - Fixed relational items with unsaved nested values, such as newly added translated items in a content version, rendering as `--` instead of their display template ([#28010](https://github.com/directus/directus/pull/28010) by @alvarosabu) - Fixed the repeater interface options showing empty sub-fields, and dropping their key and type on save, when the sub-fields were created through the API without repeating the key and type inside their meta ([#28041](https://github.com/directus/directus/pull/28041) by @lazerg) - Fixed relational fields showing stale values after a manual flow updated them ([#28056](https://github.com/directus/directus/pull/28056) by @AlexGaillard) - Fixed the Markdown interface's Edit and Preview buttons not indicating which view is currently active ([#28023](https://github.com/directus/directus/pull/28023) by @Aniket-a14) - Fixed silent failure of dragging & dropping files with an unrecognized extension into the file library ([#28093](https://github.com/directus/directus/pull/28093) by @alvarosabu) - Fixed a request for a non-existent item when opening an item whose Many-to-One field references an unsaved parent ([#27975](https://github.com/directus/directus/pull/27975) by @sourav-18) - Updated outdated type definitions for `directus_files`, `directus_collections`, `directus_deployments`, `directus_settings`, and `directus_users` ([#27945](https://github.com/directus/directus/pull/27945) by @kheiner) - Fixed field configuration appearing to close when selecting related collection that switches interface ([#28118](https://github.com/directus/directus/pull/28118) by @robluton) - Fixed the translations interface AI translation button only showing for admins ([#28089](https://github.com/directus/directus/pull/28089) by @AlexGaillard) - Fixed SSO login redirecting to the last visited page instead of the originally requested page ([#28080](https://github.com/directus/directus/pull/28080) by @AlexGaillard) - Stopped the policy creation modal from writing app access permission rows to the database, matching the policy detail page where app access permissions are applied at runtime instead of stored ([#28101](https://github.com/directus/directus/pull/28101) by @alvarosabu) - Added block-level custom formats to the WYSIWYG interface, so `block`, `selector` and `items` entries in the Custom Formats option apply classes and attributes to paragraphs, headings and other block nodes from the Formats dropdown ([#28044](https://github.com/directus/directus/pull/28044) by @alvarosabu) - Fixed WYSIWYG content the editor can't represent being hidden and unrestorable in the comparison modal ([#28067](https://github.com/directus/directus/pull/28067) by @alvarosabu) - **@directus/api** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - Added a batch-import regression test pinning that a negative temporary key maps like any other non-existent auto-increment key in merge mode ([#27861](https://github.com/directus/directus/pull/27861) by @bryantgillespie) - Updated MCP tool descriptions and safety annotations for connector clients. ([#28090](https://github.com/directus/directus/pull/28090) by @bryantgillespie) - Updated or replaced various dependencies to address GHSA-rgw5-rvv9-x895 ([#28050](https://github.com/directus/directus/pull/28050) by @br41nslug) - Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required ([#27699](https://github.com/directus/directus/pull/27699) by @br41nslug) - Updated various dependencies to address CVEs ([#28110](https://github.com/directus/directus/pull/28110) by @br41nslug) - Fixed slow extension sync from remote storage during startup. Added `EXTENSIONS_STORAGE_MAX_CONCURRENCY` to configure the maximum number of concurrent requests to the extensions storage location ([#27989](https://github.com/directus/directus/pull/27989) by @dstockton) - Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111) by @ComfortablyCoding) - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - Fixed `TranslationsService.updateMany` incorrectly rejecting single-row updates containing both `key` and `language` ([#28001](https://github.com/directus/directus/pull/28001) by @suhailopensource) - Fixed collection names with surrounding whitespace being accepted on creation ([#28038](https://github.com/directus/directus/pull/28038) by @lazerg) - Fixed WebSocket rate limiting breaking on shared Redis setups where keys must start with a per-project prefix. The WebSocket limiter now accepts `RATE_LIMITER_WEBSOCKETS_*` values as overrides, including `RATE_LIMITER_WEBSOCKETS_KEY_PREFIX` to override the Redis key prefix. ([#28107](https://github.com/directus/directus/pull/28107) by @AlexGaillard) - **@directus/storage-driver-azure** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/storage-driver-gcs** - Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted ([#28076](https://github.com/directus/directus/pull/28076) by @dstockton) - **@directus/release-notes-generator** - Updated or replaced various dependencies to address GHSA-rgw5-rvv9-x895 ([#28050](https://github.com/directus/directus/pull/28050) by @br41nslug) - **@directus/schema** - Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required ([#27699](https://github.com/directus/directus/pull/27699) by @br41nslug) - **@directus/env** - Fixed slow extension sync from remote storage during startup. Added `EXTENSIONS_STORAGE_MAX_CONCURRENCY` to configure the maximum number of concurrent requests to the extensions storage location ([#27989](https://github.com/directus/directus/pull/27989) by @dstockton) - Updated `ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION` to match `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` (`6000` px) ([#28111](https://github.com/directus/directus/pull/28111) by @ComfortablyCoding) - **@directus/extensions-registry** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - **@directus/composables** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - **@directus/extensions** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - Fixed extensions that set `sandbox` without an `enabled` flag being rejected as invalid ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton) - **@directus/errors** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - **@directus/stores** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - **@directus/utils** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - Updated ESLint dependencies `eslint`, `@eslint/js`, `eslint-plugin-vue`, and `typescript-eslint`. Replaced `eslint-plugin-import` with `eslint-plugin-import-x` ([#28047](https://github.com/directus/directus/pull/28047) by @br41nslug) - **@directus/sdk** - Removed unused dependencies across the monorepo ([#28049](https://github.com/directus/directus/pull/28049) by @ComfortablyCoding) - Fixed an unhandled rejection in the sdk realtime client when the socket errored or closed during the auth handshake ([#28009](https://github.com/directus/directus/pull/28009) by @Deluvio) - **@directus/specs** - Fixed OpenAPI spec drift, added missing query parameters, and ensured consistent parameter ordering across list endpoints ([#27938](https://github.com/directus/directus/pull/27938) by @kheiner) - **@directus/types** - Fixed extensions that set `sandbox` without an `enabled` flag being rejected as invalid ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton) - **@directus/extensions-sdk** - Fixed `extension validate` crashing on extensions with a disabled sandbox due to an invalid `findIndex` call ([#28087](https://github.com/directus/directus/pull/28087) by @dstockton) ### 📦 Published Versions - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]` - `@directus/[email protected]`