9.1.5 (2026-05-20)
Overview of merged pull requests
BUGFIX: `DimensionSpacePointsRepository’s runtime cache creates invalid state after replay <https://github.com/neos/neos-development-collection/pull/5820>`_
If the content repository was used in the same PHP instance as a replay was issued its possible to have a corrupted state and missing entries for the dimension space points.
How is this possible if projections are pure? If we rely on runtime caches to see if a write is necessary. Ironically the runtime cache for writing only “optimizes” the events DimensionShineThroughWasAdded and DimensionSpacePointWasMoved where there is not much to optimise as these are developer only emitted events.
The actual frequent inserts in the DimensionSpacePointsRepository for updated or new hierarchies and node rows where done always via INSERT IGNORE as a new instance of the DimensionSpacePointsRepository was created via new and thus the cache not shared.
This problem was noticed by accident during running the projection integrity violation detection after each scenario
https://github.com/neos/neos-development-collection/pull/5808
The feature
`
Neos.Neos/Tests/Behavior/Features/AssetUsage/DimensionSpacePoints/01-MoveDimensionSpacePoints.feature:103
`
Tests exactly just that, that after replay of the MoveDimensionSpacePoint everything is “OK” which failed before.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentGraph.DoctrineDbalAdapter
BUGFIX: Use actual occupied node rows in node aggregate (as subtree tags are hierarchy)
Previously, the subtree tags were only correctly determined if the first row of the query result is also the actual occupation node row.
See
> !isset($nodesByOccupiedDimensionSpacePoint[$occupiedDimensionSpacePoint->hash])
The attached unit tests shows that the occupations are now correctly determined.
The old behaviour is still partially in place as a (temporary) hack until we find out how to continue with https://github.com/neos/neos-development-collection/pull/5489. Because if we were strict - which we should have been in the first place - building node aggregates should not be possible without all covered rows returned. Unfortunately that exactly happens when using child queries on node aggregates with multiple parents.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentGraph.DoctrineDbalAdapter
BUGFIX: Always ensure tethered descendant node ids don’t exist during command handling
## Adjust test to not attempt to create illegal state
Following integrity violations are detected:
Node aggregate nodewyn-tetherton is ambiguous in content stream cs-identifier and dimension space point {“language”:”gsw”},
Node aggregate nodewyn-tetherton in content stream cs-identifier is of ambiguous type (“Neos.ContentRepository.Testing:ChildOfNodeTypeA”,”Neos.ContentRepository.Testing:Tethered”)
see https://github.com/neos/neos-development-collection/issues/5795
## Test and implement that tetheredDescendantNodeAggregateIds are not occupied
CreateRootNodeAggregateWithNodewas already implemented but not testedCreateRootNodeAggregateWithNodeandChangeNodeAggregateTypeallowed to create illegal state in the projections
Packages:
ContentRepository.BehavioralTests
BUGFIX: Ignore orphaned reference relations in integrity violation
solves: https://github.com/neos/neos-development-collection/issues/5795
As per #5809 orphaned reference edges are a design decision - at least for the released Neos 9.0 version(s). To prevent confusing users and also to allow us to run the projection integrity violation detection after each test scenario in ci, we silence the error in that specific case.
Review commit by commit please if you dont think this change is harmless;)
Packages:
ContentGraph.DoctrineDbalAdapterContentRepository.BehavioralTests
BUGFIX: Stabilise behavioural CR test for PostgreSQL graph
Based on https://github.com/neos/neos-development-collection/pull/5791
Extracted from #5751
Fix assertion on DSP
affectedCoveredDimensionSpacePointsin behavioural testsuiteFix sequence numbers for postgres test setup
the second fix, truncating the event table in the behaviour tests like that was a Provisorium already and touching this code begs the question if we can also find a better way - even only for the future, so lets discuss.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentRepository.TestSuite
BUGFIX: SoftRemoval: Avoid uneccessary queries which become costly with many workspaces
In withVisibleInDependingWorkspacesConflicts we invoke for every workspace $contentGraph->findNodeAggregatesByIds() This is intended and the fastest way with the current API, but its relatively useless when $softRemovedNodes are empty as there will be no objections to be found.
Found during benching with 1000 workspaces and publications.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
FusionNeos
BUGFIX: Add missing neos link styles in Minimal css
When a package uses the Minimal option as the main stylesheet, some link styles were missing, and the underlines in the side navigation and the breadcrumbs were rendered while the package was active. A prominent example is Flowpack/Media/Ui.
This fix adds styles to specific CSS selectors to avoid breaking changes in unexpected places.
Before:
<img width=”1460” height=”767” alt=”Bildschirmfoto 2026-04-14 um 11 54 44” src=”https://github.com/user-attachments/assets/771efdb8-f53e-44ed-bdca-5c745083fb01” />
After:
<img width=”1469” height=”773” alt=”Bildschirmfoto 2026-04-14 um 11 43 29” src=”https://github.com/user-attachments/assets/2ed0da6d-a554-40a7-91da-983a42da3583” />
related: Bug in Flowpack/media-ui
Packages:
Neos
BUGFIX: Introduce `ProjectionIntegrityViolationDetectionRunnerFactoryInterface to allow switching implementation via Objects.yaml <https://github.com/neos/neos-development-collection/pull/5791>`_
Non breaking and clean way to allow custom graphs to be implemented. Leverages the Framework to determine the implementation rather than adding the concept to the ContentRepository object itself which would be partly breaking custom implementations.
The need came up with #5751
And extract shared ProjectionIntegrityViolationDetectionTrait from DBAL specific implementation
removes all autoloading hacks
allows custom content graph implementations to be tested without DBAL adapter and autoloading issues
objects.yaml determines which ProjectionIntegrityViolationDetection to use
Packages:
NeosContentGraph.DoctrineDbalAdapterContentRepository.BehavioralTestsContentRepository.TestSuite
BUGFIX: Update version and release to 8.4 in conf.py
The documenttation for 8.4 claimed to be 8.3 on https://neos.readthedocs.io/en/8.4/.
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[x] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[x] Reviewer - The first section explains the change briefly for change-logs
[ ] ~~Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions~~
Packages:
Neos
BUGFIX: Prevent unsigned integer underflow in DocumentUriPathProjection when duplicate SubtreeWasUntagged events reach live
Before decrementing the disabled/removed counter, check whether the node was actually explicitly tagged by comparing its counter with the parent node’s counter. If the node’s level is not greater than the parent’s, the untag is a no-op — preventing 0 - 1 on the UNSIGNED column.
Resolves: #5778
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentRepository.TestSuite
BUGFIX: Find reference nodes by their aggregate id
Adjusts the nodes service endpoint to include a node if its id equals the specified search term
Fixes: #5756
Related: https://github.com/neos/neos-ui/pull/4093
Packages:
Neos
BUGFIX: Partial Publishing node type changes did not work if child nodes were removed (because constraints did not match anymore)
### Problem
Publishing a workspace could fail with PartialWorkspaceRebaseFailed after a ChangeNodeAggregateType command was executed using the delete strategy:
`
ServerSideError: Neos\\ContentRepository\\Core\\Feature\\WorkspaceRebase\\Exception\\PartialWorkspaceRebaseFailed
Publication failed, events cannot be reordered as filtered:
"Node aggregate "62671e14-…" does currently not exist."
`
## Reproduction steps:
Create a page — and ensure this auto-creates a tethered child node (e.g. a content collection)
Insert content into the tethered child node (e.g. Text)
Change the page’s node type to one that no longer declares the tethered node (e.g. a Shortcut). This then applies
strategy: deletePublish all changes via “Publish All” in the Content Module -> this triggers a Partial Publish in all cases.
The original command order on the user workspace is:
Create Page (also creates tethered ContentCollection)
Create Text
ChangeNodeAggregateType (Page -> Shortcut) - auto-emits a “NodeAggregateWasRemoved”
this removes the tethered node + Text node physically from the user workspace
The delete strategy emitted NodeAggregateWasRemoved events, physically removing the tethered node and its children. Because of this physical removal, the tethered child node’s ID cannot be detected during partial publishing, and thus the content creation (from step 2) is sorted not as “to-be-publishedCommands”, but “remainingCommands”.
Thus, the order used during partial publish will be:
to be published - Create Page (also creates tethered ContentCollection) - ChangeNodeAggregateType (Page -> Shortcut)
auto-emits a “NodeAggregateWasRemoved”
remainingCommands - Create Text <– WRONG (no existing parent, as it has been removed in a previous step)
There exist multiple variations of the above bug, all caused by the same mechanism described above.
### Solution
A new ``markWithTag`` strategy is introduced for ChangeNodeAggregateType. Instead of emitting NodeAggregateWasRemoved, it emits SubtreeWasTagged, which hides the disallowed nodes via a SubtreeTag (“soft delete”). The node aggregates remain in the graph, so workspace rebase can still resolve event references — no ordering conflict occurs.
After publishing, soft removals are already physically removed.
NOTE: This needs a corresponding change in Neos.Neos.Ui/Classes/Domain/Model/Changes/Property.php to use this Soft Removal: https://github.com/neos/neos-ui/pull/4099
### Implementation Details
I needed to convert NodeAggregateTypeChangeChildConstraintConflictResolutionStrategy from an ENUM to a class, in order to store the additional tag-information for the new strategy.
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentRepository.Core
BUGFIX: Stabilize Workspace preview for broken assets
Prevents missing assets from throwing an exception when trying to review workspace changes:
### Before
<img width=”978” height=”340” alt=”image” src=”https://github.com/user-attachments/assets/5d06b99a-ccbe-43df-b71f-9e05b1783dc6” />
### With fix
<img width=”1842” height=”1127” alt=”image” src=”https://github.com/user-attachments/assets/e33818ad-5d0e-4653-9c51-d753f44ec078” />
Fixes: #5754
Packages:
Neos
BUGFIX: Log `fusionPath when absorbing exceptions during Fusion rendering <https://github.com/neos/neos-development-collection/pull/5760>`_
The AbsorbingHandler is active by default and will log the current fusionPath and referenceCode to the System Log. But it is not logged with the exception itself and there is no way to correlate the two (apart from the timestamp).
This fix adds fusionPath and referenceCode to the additionalData array, making them appear in the exception log, too.
Packages:
NeosFusion
TASK: Decouple postgreSQL adapter from dev collection for beta development
See https://github.com/neos/neos-development-collection/pull/5751#issuecomment-4278834816
See also https://github.com/neos/slicer/pull/24 which disables slicing
And https://github.com/neos/contentgraph-postgresqladapter/issues/2 the roadmap to the first beta.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentGraph.PostgreSQLAdapter
TASK: Allow configuration yaml format in behaviour tests
The GherkinTableNodeBasedContentDimensionSource currently does not allow configuration values, which prevents tests from being written that need this.
~This adds an arbitrary amount of JSON that can be used as config for dimensions and dimension values~
This adds a new step which can be used as replacement:
```feature Given using the following content dimensions yaml configuration: “””yaml language:
label: ‘Neos.Demo:Main:contentDimensions.language’ icon: language values:
- ‘en_US’:
label: English (US) specializations:
- ‘en_UK’:
label: English (UK)
- ‘de’:
label: Deutsch
“””
Upgrade instructions
none
Review instructions
mainly check the JSON format
Packages:
ContentRepository.TestSuite
TASK: Sane visibility constraints in behaviour tests
Requires: https://github.com/neos/neos-development-collection/pull/5817
### Use visibility constraints only for testing queries (see NodeTraversal)
and not for general node assertions
if mixed together understanding the tests becomes quickly absurd as there are lot-of checks asserting a node does not exist, but they mean they are _hidden_. Which becomes really fun to read if the visibility constraints are multiple times modified in a test.
instead writing tests should always take into account that the nodes exist
In combination with the following steps assertions should become more readable
before
`
I expect node aggregate identifier "mc-nodeface" to lead to no node
`
after
`
I expect node aggregate identifier "mc-nodeface" to lead to node cs-identifier;mc-nodeface;{}
I expect this node to be exactly explicitly tagged "disabled"
I expect this node to exactly inherit the tags "disabled"
`
completely separate from that are assertions for queries. While internally the findNodeById query is also used for
> I expect node aggregate identifier “mc-nodeface” to lead to node cs-identifier;mc-nodeface;{}
the test describes just the expectation and the test-writer should not think about any possible filtering or exact queries.
for testing queries explicitly it makes sense to take visibility constraints into account
`
And I restrict the visibility of nodes tagged "disabled" in subgraph queries
When I execute the findChildNodes query for parent node aggregate id ...
`
TODO: - [ ] Ensure by no longer using VisibilityConstraints for node disabling assertions we add capable tests for NodeTraversal
[ ] Add for NodeTraversal second tag on a parent node which is excluded in another scenario to show inheritance works
Packages:
ContentRepository.TestSuite
TASK: (Slightly) improve workspace / publishing test coverage
Required for #5776 We need to improve test-coverage for publication to ensure all commands only affect the one workspace they were applied in. This is only natural in the current 9.0 forking model where we copy the whole hierarchy but with optimisations the code becomes more complex and some tests might still pass when modifying all workspaces simultaneously accidentally.
CreateRootNodeAggregateWithNode (Added)
CreateNodeAggregateWithNodeAndSerializedProperties (9.0)
SetSerializedNodeProperties (Added)
MoveNodeAggregate (Todo, Added)
RemoveNodeAggregate (9.0) One duplicate historical case removed (where RemoveNodesFromAggregate was a separate command)
ChangeNodeAggregateName (Commented) Testcase repaired and enabled
ChangeNodeAggregateType (Added)
CreateNodeVariant (Todo)
TagSubtree (9.0)
UntagSubtree (9.0)
UpdateRootNodeAggregateDimensions
SetSerializedNodeReferences (9.0)
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
ContentRepository.BehavioralTests
TASK: Use commands instead of events in behaviour tests
… in order to prevent impossible states
Followup to https://github.com/neos/neos-development-collection/pull/4335
Fixes: #4336 (finally :D)
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentRepository.BehavioralTests
TASK: Adjust to use correct `neos/behat subcontext in ci <https://github.com/neos/neos-development-collection/pull/5803>`_
Requires https://github.com/neos/neos-development-collection/pull/5284
With https://github.com/neos/behat/pull/42 the FLOW_CONTEXT is respected
as we specify FLOW_CONTEXT: Testing behat now fails as the context must either not be defined or set to Testing/Behat or Testing/Behat/*
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
.github
TASK: Remove doctrine migrate and cr setup commands from behat scripts
Alternative fix to #5005 <https://github.com/neos/neos-development-collection/issues/5005>``_or the commits in ``#4988
When the ci is run without the doctrine schema setup the behat helper @flowEntities will create the schema.
This unfortunately messes with the transaction level as debugged:
``` array(2) {
[“getTransactionNestingLevel”]=> int(119) [“isTransactionActive”]=> bool(true)
}
The working state - when the schema exists already - looks like this
``` array(2) {
[“getTransactionNestingLevel”]=> int(0) [“isTransactionActive”]=> bool(false)
}
The CI complains with errors like
> A transaction is active already, can’t commit events!
or
> Failed to acquire checkpoint lock for subscriber “Neos\ContentRepository\Core\Projection\ContentStream\ContentStreamProjection” because a transaction is active
But with https://github.com/neos/behat/pull/40 we fix the problem and reset the transactions after the migration, so that we can remove the ci hack ./../flow doctrine:migrate.
Upgrade instructions
Packages:
Neos
TASK: Log events if parallel tests failed
To better and fully understand https://github.com/neos/neos-development-collection/issues/5713 we output the last 100 events in case of an error.
Upgrade instructions
Review instructions
If it’s a bugfix, use the lowest maintained branch which has the bug
If it’s a non-breaking feature, use the branch of the next version (might be either minor or major)
If it’s a breaking feature it should typically go into the next major version
[ ] Reviewer - PR Title is brief but complete and starts with
FEATURE|TASK|BUGFIX[ ] Reviewer - The first section explains the change briefly for change-logs
[ ] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
NeosContentRepository.BehavioralTests