Skip to main content
Version: Next

Upgrade Information

The following steps are necessary during updating to newer versions.

Upgrade to 2026.4.0​

Embeddings​

  • New embeddings.models.<id>.field_filter: per model and data object class an allow or a block list of grid column keys, optionally narrowed to one language as {key, locale}. Absent, every field is embedded as before. See Filters tab.
  • embeddings.excluded_fields is deprecated in favour of field_filter, emits a deprecation at container build, and will be removed in 2027.1.0. Until then it keeps working, and still removes a key an allow list names.
  • An element a filter leaves with nothing to embed loses that model's stored vector and text siblings on the next re-embed, instead of keeping the ones it had. It counts as processed from then on, so a full re-embed completes with such elements in scope. An element out of scope keeps its vectors as before.
  • A mode: allow entry naming an image, geo or URL-slug key exactly embeds it; password and encryptedField never are. Without a field_filter nothing changes.
  • Studio API: the configuration carries allowListFilters and blockListFilters; each entry's fields comes back as stored plus a read-only inactive flag.
  • bpt:embeddings:search-eval --dump-text composes with the model bound to semantic_text_search, and fails when that usage has no model.
  • auth_token and options.headers of an embedding model now reject unescaped %name% parameter references in addition to %env(...)% placeholders, in Studio, in config/packages/*.yaml and in the embeddings write-target yaml. A configuration that uses one fails validation after the update; replace it with the literal value, or escape a literal % as %%.
  • On Studio saves and uploads, the text of document and plain-text assets is extracted by the index queue worker instead of during the request, so their vectors appear once the worker has processed the asset.
  • Inputs the provider rejects permanently (HTTP 400/413/422) are isolated and stamped with an emb_<model>[__<format>]_failed timestamp; the bpt_embedding_reconcile maintenance task retries them at most once every 24 hours. No index recreation is needed.

Duplicates Detection​

  • A running analysis can only be canceled by the user who started it or by an admin

Semantic Search (experimental)​

  • Semantic grid search now cuts off weak matches with a default minimum score (text 20 %, image 8 %) instead of returning the top 150 hits. Set semantic_search.targets.<text|image>.default_min_score to 0 (or send minScore: 0) to keep every hit.
  • Candidates per search are limited by semantic_search.candidate_cap (default 10000) instead of 150, so totals and paging go deeper; lower the cap on large indexes if searches get slow.
  • The global semantic search endpoint applies the same default minimum score; its candidates per index are configurable via semantic_search.global_search_candidate_cap (default 150, unchanged).
  • CSV/XLSX exports and batch actions of a semantic grid now apply the semantic filter with the job owner's permissions, so they contain the same elements as the grid.
  • When the inference service cannot embed the query, grid smart search, its exports and its batch actions now fail with a user-facing error (bpt_semantic_search_unavailable) instead of returning non-semantic results; export and batch jobs end as failed. The global semantic search endpoint returns the same message.
  • New semantic_search configuration record (System → Semantic Search Configuration); run the migrations to seed it.
  • Requires pimcore/studio-backend-bundle, pimcore/studio-ui-bundle and pimcore/generic-data-index-bundle 2026.4.

Upgrade to 2026.3.5​

  • [Security] Alternative Element Trees: the Symfony expression of a relation tree level (relationSymfonyExpression) is now evaluated with read-only values of the related object (GHSA-x6vx-2g29-6ff4). Symfony's ExpressionLanguage is not a sandbox: anyone allowed to edit tree configurations could call every public method of the related object, e.g. reach the database connection through object.getDao(), or save or delete elements. Field getters (also of related objects, object bricks, field collections and localized fields, e.g. object.getName("de")), element getters (getId(), getKey(), getFullPath(), getParent(), dates, ...), the getters of field values and operators like ~ keep working, e.g. object.getName() ~ " " ~ object.getManufacturer().getName(). Any other method, e.g. getDao(), save(), delete(), setters, getClass() or getChildren(), is rejected: saving such a tree configuration fails validation, and a stored one fails when the tree is built. The constant() function stays unavailable. See the Pimcore core upgrade notes on expressions for the full list.
  • pimcore/pimcore ^2026.3.5 is now required, as it provides the read-only expression language.

Upgrade to 2026.3.4​

  • Alternative Element Trees: the hash that detects whether an object's tree rows must be rebuilt now keeps empty levels and the borders between levels. Stored hashes change, so each object is re-checked the next time it is saved and its rows are rebuilt once. To repair trees that already hold stale rows, run bin/console bpt:aet:rebuild-tree -a.

Upgrade to 2026.3.3​

  • Duplicate detection: a sweep page whose search request times out (cluster_courtesy.request_timeout_ms) or comes back with a failed shard now aborts that sweep step, so the run ends finished with errors instead of silently finished with incomplete results. The failed page is not checkpointed, so the run never records progress past what it missed. The run keeps a single resume cursor, though: once the fuzzy tier has checkpointed, a retry of a failed exact sweep starts from the beginning rather than at the last exact page. If runs now end with errors, raise request_timeout_ms or check the search cluster's health.
  • Duplicate detection: a run that stopped at an execution budget before covering every element now shows a warning on the duplicates configuration screen.

Upgrade to 2026.3.2​

  • Duplicate detection: the path restriction of a scope or class is now a list of include/exclude folder rules (paths) and applies to group members as well as references, in both the exact and the fuzzy tier. Previously the fuzzy tier could group elements from outside the configured path. The next analysis withdraws such members; no full run is needed.
  • path_prefix is deprecated; it is read as one include rule. Replace it with paths, see Folder rules.
  • A path now covers whole folders only: /Products no longer matches /Products-Old.
  • Studio API: the duplicates configuration schemas carry paths (list of {path, mode}); the former pathPrefix is deprecated and, when paths is empty, still read as one include rule.

Upgrade to 2026.3.0​

  • Added Embeddings (experimental) – off by default.
  • New public API - EmbeddingProviderInterface, AbstractHttpEmbeddingProvider, EmbeddingModelConfig and EmbeddingConfigException are public so a custom provider can be implemented.

Embeddings are adding a new table, please execute the migration command after updating the bundle:

bin/console doctrine:migrations:migrate --prefix='Pimcore\Bundle\BackendPowerToolsBundle\Migrations'

Upgrade to 2026.2.6​

Frontend Build Ships as a Packaged Archive​

The compiled Studio frontend is no longer committed as an expanded public/studio/build/ directory. It now ships as a single archive (build-dist/build-<id>.zip) that is extracted into public/studio/build/ automatically during cache warmup.

pimcore/studio-ui-bundle ^2026.2.1 is now required, as it provides the archive extraction.

Note: Read-only filesystem deployments must run bin/console cache:warmup (or cache:clear) during the build/deploy phase while the bundle directory (usually under vendor/) is still writable. Standard Pimcore deployments already do this. When assets:install runs in copy mode, run cache:warmup before it, otherwise no frontend assets are copied. If the filesystem becomes read-only before the first warmup, the bundle fails with BuildArchiveNotWritableException because there is no build to serve.

Upgrade to 2026.1.0​

  • The bundle installer now implements PostInstallCommandsProviderInterface from Pimcore's InstallBundle. This means the post-install command bpt:aet:rebuild-tree -a is automatically executed during pimcore:install when using Install Profiles. Manual execution of this command after pimcore:bundle:install is still required as before.
  • The messenger transport DSN is now configurable via the %pimcore.messenger.transport_dsn_prefix% container parameter instead of being hardcoded to doctrine://default. This allows the installer to wire the transport DSN from environment variables (e.g. PIMCORE_MESSENGER_TRANSPORT_DSN_PREFIX).
  • Added support to PHP 8.5.
  • Removed support to PHP 8.3 and Symfony v6.