# Release v1.51.0-next.3 Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.51.0-next.3](https://backstage.github.io/upgrade-helper/?to=1.51.0-next.3) ## @backstage/plugin-scaffolder-backend@4.0.0-next.2 ### Major Changes - c78b3b6: Add explicit memory management to SecureTemplater usage ### Minor Changes - 8006acf: The template parameter schema response now exposes a `formDecorators` field instead of `EXPERIMENTAL_formDecorators`. Templates that still declare `spec.EXPERIMENTAL_formDecorators` are read transparently and surfaced under the new field. ### Patch Changes - 1ecc3ca: Fixed spelling mistakes in internal code - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/plugin-scaffolder-common@2.2.0-next.1 - @backstage/plugin-scaffolder-node@0.13.3-next.2 ## @backstage/integration-aws-node@0.2.0-next.1 ### Minor Changes - 8df06ec: Added `webIdentityTokenFile` to `AwsIntegrationAccountConfig` and `AwsIntegrationDefaultAccountConfig`. When set along with a `roleName`, `DefaultAwsCredentialsManager` retrieves credentials by calling `AssumeRoleWithWebIdentity` (via `fromTokenFile`) using the file's contents as the web identity token. The file is re-read on each credential refresh. The validator rejects combining `webIdentityTokenFile` with `accessKeyId`/`secretAccessKey`, `profile`, or `externalId`, and rejects setting it without a `roleName`. ## @backstage/plugin-catalog-backend@3.7.0-next.2 ### Minor Changes - c2de113: **BREAKING**: When paginating entities with an order field via `/entities/by-query`, entities that lack the order field are now excluded from both the result set and the `totalItems` count. Previously these entities appeared at the end of the sorted result via `NULLS LAST`, but cursor-based pagination could not actually reach them past the first page — the count over-reported the number of navigable entities. The new behavior aligns the count with what is actually returned. This also removes the `DISTINCT` deduplication from the sort-field CTE, which is a prerequisite for the planner to use the `(key, value, entity_id)` index in sort order and short-circuit on `LIMIT`. Installations with duplicate search rows should land the search-table deduplication migration before adopting this change. ### Patch Changes - ccbad9d: Improved the performance of the `catalog_entities_count` metric. The legacy Prometheus and OpenTelemetry observable gauges previously each ran their own copy of the per-kind count query against the `search` table on every metrics scrape. On large catalogs this could pile up faster than the queries completed, contending for buffers and stalling the database. The two callbacks now share a single query result with a short in-process TTL cache, and the underlying query reads from `final_entities` instead of `search`, avoiding the bitmap heap scans that dominated the previous form. The emitted labels and values are unchanged. - add5d1a: Restructured the entity listing endpoint so that, when a sort field is specified, the search-by-key index drives the query rather than being side-joined onto `final_entities`. This lets PostgreSQL walk the `(key, value, entity_id)` index in already-sorted order and short-circuit on `LIMIT`, reducing typical broad-filter paginated list times from seconds to milliseconds. Entities that lack the sort field still appear at the end of sorted results (NULLS LAST semantics preserved), ordered by `entity_id`. - 387ea7d: Simplified the entity facets aggregation from `COUNT(DISTINCT entity_id)` to `COUNT(*)`. The unique constraint on `(entity_id, key, value)` guarantees each entity appears at most once per search row group, making the `DISTINCT` unnecessary. This allows the database to use a simpler aggregation plan. - 3f55b73: Improved the performance of the entity facets endpoint when filters are applied. The filtered entity set is now combined with the search table through an inner join rather than a `WHERE entity_id IN (subquery)`. Results are unchanged; on large catalogs the query planner is able to choose dramatically cheaper plans, with measured improvements ranging from roughly 1.2× on already-fast cases to 7× or more on high-cardinality facets. - cde3643: Added missing description to the `type` parameter on the `unregister-entity` MCP action. - 7445f0f: Added a migration that removes duplicate rows from the `search` table, creates covering indices for improved query performance, and adds a `UNIQUE` constraint on `(entity_id, key, value)`. This is a long-running migration on large catalogs. On PostgreSQL with millions of search rows, the index creation may take 5-15 minutes per index. During this time, other pods running the previous version will continue to serve traffic normally — the index creation does not block reads or writes. However, if a Kubernetes liveness probe kills the pod before the index build completes, the build is lost and the next startup will start over. On large tables this can repeat indefinitely. **For large installations**, it is recommended to run the following SQL commands against your PostgreSQL database **before deploying** this version. Each index build takes a few minutes but does not block reads or writes. If these have already completed, the migration will detect the existing indices and skip all work — startup will be instant. ```sql -- Step 1: Remove duplicate search rows WITH cte AS ( SELECT ctid, row_number() OVER (PARTITION BY entity_id, key, value) AS rn FROM search ) DELETE FROM search USING cte WHERE search.ctid = cte.ctid AND cte.rn > 1; -- Step 2: Create new indices (run each separately) CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS search_entity_key_value_idx ON search (entity_id, key, value); CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_value_entity_idx ON search (key, value, entity_id); CREATE INDEX CONCURRENTLY IF NOT EXISTS search_facets_covering_idx ON search (key, original_value, entity_id) WHERE original_value IS NOT NULL; -- Step 3: Drop old indices that are no longer needed DROP INDEX CONCURRENTLY IF EXISTS search_key_value_idx; DROP INDEX CONCURRENTLY IF EXISTS search_key_original_value_idx; ``` Also fixed `buildEntitySearch` to remove duplicate output for entities with duplicate array values, and added `ON CONFLICT DO UPDATE` to `syncSearchRows` so that concurrent stitching races are handled gracefully. - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/plugin-scaffolder@1.37.0-next.2 ### Minor Changes - dbeb7aa: Added experimental BUI (Backstage UI) form theme for scaffolder forms. All default field extensions render BUI variants when enabled. **Extension config:** ```yaml app: extensions: - sub-page:scaffolder/templates: config: enableBackstageUi: true ``` **JSX props:** ```tsx ``` - 8006acf: Promoted `formDecoratorsApiRef`, `ScaffolderFormDecoratorsApi`, `DefaultScaffolderFormDecoratorsApi`, and `formDecoratorsApi` from `@alpha` to `@public`. - d09c21c: The `sub-page:scaffolder/templates` extension now accepts a `groups` config field that lets you define template groups on the template list page. Each group has a `title` and a `filter` predicate. Templates not matched by any configured group fall into an automatically appended "Other Templates" group. With no groups configured, the page renders a single "Templates" group as before. Example: ```yaml app: extensions: - sub-page:scaffolder/templates: config: groups: - title: Recommended Services filter: spec.type: service - title: Documentation filter: spec.type: documentation ``` ### Patch Changes - 1ecc3ca: Fixed spelling mistakes in internal code - 8006acf: Form decorator input is now parsed against the zod schema configured on the decorator before the decorator runs, so defaults declared via `.default()` are applied and invalid input is reported through the error API instead of silently passing through. - 8006acf: The template wizard now reads form decorators from the new `spec.formDecorators` field on a template, falling back to the deprecated `spec.EXPERIMENTAL_formDecorators` for templates that have not been migrated. - Updated dependencies - @backstage/plugin-scaffolder-react@1.21.0-next.1 - @backstage/ui@0.15.0-next.3 - @backstage/plugin-scaffolder-common@2.2.0-next.1 - @backstage/plugin-catalog-react@2.1.5-next.1 ## @backstage/plugin-scaffolder-common@2.2.0-next.1 ### Minor Changes - 8006acf: Promote the `formDecorators` field on the `Template` spec out of experimental. The previous `EXPERIMENTAL_formDecorators` field continues to work and is kept as a deprecated alias. ## @backstage/plugin-scaffolder-react@1.21.0-next.1 ### Minor Changes - dbeb7aa: Added experimental BUI (Backstage UI) form theme for scaffolder forms. All default field extensions render BUI variants when enabled. **Extension config:** ```yaml app: extensions: - sub-page:scaffolder/templates: config: enableBackstageUi: true ``` **JSX props:** ```tsx ``` - 8006acf: Promoted `FormDecoratorBlueprint` and `ScaffolderFormDecorator` from `@alpha` to `@public`. - d09c21c: The `TemplateCard` component is now a swappable component. Apps using the new frontend system can replace it by registering a `SwappableComponentBlueprint` that targets `TemplateCard`. Components used as the swappable implementation receive `TemplateCardComponentProps`, where `onSelected` is a zero-argument callback bound to the rendered template. Existing usage continues to work unchanged. ### Patch Changes - Updated dependencies - @backstage/ui@0.15.0-next.3 - @backstage/plugin-scaffolder-common@2.2.0-next.1 - @backstage/plugin-catalog-react@2.1.5-next.1 ## @backstage/backend-defaults@0.17.1-next.2 ### Patch Changes - 90b572e: Adds an alpha `TracingService` to provide a unified interface for emitting trace spans across Backstage plugins. - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/backend-dynamic-feature-service@0.8.2-next.1 ### Patch Changes - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 - @backstage/plugin-catalog-backend@3.7.0-next.2 - @backstage/plugin-scaffolder-node@0.13.3-next.2 ## @backstage/backend-plugin-api@1.9.1-next.1 ### Patch Changes - 90b572e: Adds an alpha `TracingService` to provide a unified interface for emitting trace spans across Backstage plugins. ## @backstage/backend-test-utils@1.11.3-next.2 ### Patch Changes - 7fb12b8: Added a new tracing service mock to be leveraged in tests - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 ## @backstage/create-app@0.8.3-next.3 ### Patch Changes - 14e2056: Pinned the Jest version range in app templates to `~30.2.0` to prevent automatic upgrades to Jest 30.4.x, which requires Node.js v24.9+ and breaks tests on Node 22. ## @backstage/ui@0.15.0-next.3 ### Patch Changes - 4bb649d: Fixed Table with row selection creating phantom scroll height on ancestor elements by establishing a containing block for visually-hidden checkbox inputs. **Affected components:** Table, TableRoot - d726bcd: Added new `DatePicker` component — combines a date field and a calendar popover for selecting a date, built on React Aria with full keyboard and screen reader accessibility. Uses BUI design tokens throughout, including auto-incremented backgrounds via the bg consumer pattern. **Affected components:** DatePicker ## @backstage/plugin-app@0.4.6-next.2 ### Patch Changes - a345820: The `app/routes` redirect config now supports path parameter substitution in the `to` target. Named params (`:userId`) and splat params (`*`) captured by the `from` path are replaced in the `to` string before navigating, making it possible to express redirects like: ```yaml app: extensions: - app/routes: config: redirects: - from: /users/:userId to: /profile/:userId - from: /old-docs to: /docs/* ``` - Updated dependencies - @backstage/ui@0.15.0-next.3 ## @backstage/plugin-auth@0.1.8-next.2 ### Patch Changes - 4f62755: Improved the OAuth consent dialog for MCP authorization by showing more client details, including the client metadata host for CIMD clients, the metadata URL, callback URL, and requested scopes. - Updated dependencies - @backstage/ui@0.15.0-next.3 ## @backstage/plugin-auth-backend@0.28.1-next.2 ### Patch Changes - 4f62755: Improved the OAuth consent dialog for MCP authorization by showing more client details, including the client metadata host for CIMD clients, the metadata URL, callback URL, and requested scopes. - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/plugin-catalog@2.0.5-next.1 ### Patch Changes - 728629c: Fixed an issue where navigating to an unknown sub-path on an entity page (for example `/catalog/default/component/foo/blob`) would silently render the first available route. Unknown paths now show the standard not-found page instead. - Updated dependencies - @backstage/ui@0.15.0-next.3 - @backstage/plugin-scaffolder-common@2.2.0-next.1 - @backstage/plugin-catalog-react@2.1.5-next.1 ## @backstage/plugin-catalog-backend-module-aws@0.4.23-next.2 ### Patch Changes - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 ## @backstage/plugin-catalog-backend-module-gitlab@0.8.3-next.2 ### Patch Changes - 1ecc3ca: Fixed spelling mistakes in internal code - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 ## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.12-next.2 ### Patch Changes - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 - @backstage/plugin-catalog-backend@3.7.0-next.2 ## @backstage/plugin-catalog-backend-module-logs@0.1.22-next.1 ### Patch Changes - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/plugin-catalog-backend@3.7.0-next.2 ## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.20-next.1 ### Patch Changes - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/plugin-scaffolder-common@2.2.0-next.1 ## @backstage/plugin-kubernetes-backend@0.21.4-next.1 ### Patch Changes - 1ecc3ca: Fixed spelling mistakes in internal code - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/plugin-kubernetes-react@0.5.19-next.1 ### Patch Changes - e68cb8a: Added optional clustersCacheTtlMs option to KubernetesBackendClient that caches getClusters() responses for the specified duration, avoiding repeated /clusters requests when multiple proxy calls resolve cluster auth in quick succession. ## @backstage/plugin-notifications-backend-module-email@0.3.21-next.1 ### Patch Changes - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/plugin-scaffolder-node@0.13.3-next.2 ### Patch Changes - Updated dependencies - @backstage/backend-test-utils@1.11.3-next.2 - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/plugin-scaffolder-common@2.2.0-next.1 ## @backstage/plugin-search-backend-module-elasticsearch@1.8.3-next.2 ### Patch Changes - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 ## @backstage/plugin-techdocs-node@1.15.0-next.2 ### Patch Changes - Updated dependencies - @backstage/integration-aws-node@0.2.0-next.1 - @backstage/backend-plugin-api@1.9.1-next.1 ## example-app@0.0.35-next.1 ### Patch Changes - Updated dependencies - @backstage/plugin-app@0.4.6-next.2 - @backstage/plugin-scaffolder-react@1.21.0-next.1 - @backstage/plugin-scaffolder@1.37.0-next.2 - @backstage/plugin-catalog@2.0.5-next.1 - @backstage/ui@0.15.0-next.3 - @backstage/plugin-auth@0.1.8-next.2 - @backstage/plugin-catalog-react@2.1.5-next.1 ## example-app-legacy@0.2.121-next.1 ### Patch Changes - Updated dependencies - @backstage/plugin-scaffolder-react@1.21.0-next.1 - @backstage/plugin-scaffolder@1.37.0-next.2 - @backstage/plugin-catalog@2.0.5-next.1 - @backstage/ui@0.15.0-next.3 - @backstage/plugin-catalog-react@2.1.5-next.1 ## example-backend@0.0.50-next.3 ### Patch Changes - Updated dependencies - @backstage/backend-plugin-api@1.9.1-next.1 - @backstage/backend-defaults@0.17.1-next.2 - @backstage/plugin-scaffolder-backend@4.0.0-next.2 - @backstage/plugin-catalog-backend@3.7.0-next.2 - @backstage/plugin-kubernetes-backend@0.21.4-next.1 - @backstage/plugin-auth-backend@0.28.1-next.2 - @backstage/plugin-search-backend-module-elasticsearch@1.8.3-next.2 - @backstage/plugin-catalog-backend-module-logs@0.1.22-next.1 - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.20-next.1 ## @internal/scaffolder@0.0.21-next.1 ### Patch Changes - Updated dependencies - @backstage/plugin-scaffolder-react@1.21.0-next.1