9.0.14 (2026-07-16)
Overview of merged pull requests
BUGFIX: Deterministic ordering of NodeAggregates’ Nodes for emitting events
Requires https://github.com/neos/neos-development-collection/pull/5883
Due to the removed ORDER BY we might also see slight query performance improvements
### Query findNodeAggregatesById()
This PR now insures that we order Nodes $occupiedDimensionSpacePoints before emitting events based on order.
Before the order returned from the database was used. This was determined by ORDER BY n.relationanchorpoint DESC.
But this order is highly adapter specific in this case it depends on internal (relationanchorpoint) from the M*SQL graph implementation that has no public defined behaviour.
Nodes in an aggregate are unordered!!!
Related https://github.com/neos/neos-development-collection/pull/5817
### Query findNodeAggregatesByIds() and findNodeAggregatesTaggedBy()
Tests were now adjusted to sort the results alphabetically before comparing them to avoid any ordering mismatches as the database does not define an order.
Also the soft-removal-garbage-collector was adjusted to sort the result from findNodeAggregatesTaggedBy() alphabetically to have a deterministic order for testing.
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.CoreContentRepository.StructureAdjustment
BUGFIX: Prevent command handling (`NodeTypeChange) on currently invalid dimension subspace <https://github.com/neos/neos-development-collection/pull/5883>`_
Preparation for https://github.com/neos/neos-development-collection/pull/5824
### Require all dimensions of NodeAggregate to be allowed during NodeTypeChange
During looping over the occupied nodes we should ensure that we don’t sort out or keep invalid dimension space points. That can happen when a dimension was renamed via configuration or removed.
Now we require that the dimension configuration is still up to date with the NodeAggregate (with `#5824 <https://github.com/neos/neos-development-collection/issues/5824>`_also for its children) which are attempted to be changed.
That is a sane limitation and during node create and create variate already enforced where we specify the dimensions explicitly. There we use requireDimensionSpacePointToExist to ensure the provided DSP’s of the command are allowed and requireNodeAggregateToOccupyDimensionSpacePoint to further check if we can vary a node or create a child node.
Now because NodeTypeChange affects all dimensions we dont require to provide any dimension space points and thus dont validate that they are allowed. Still we take all covered dimension space points of the NodeAggregate and do further calculations. That is rather implicit to ensure there are no unexpected side-effects when reading both from the NodeAggregate and partially from the variation graph we first fully ensure that the node aggregate is up to date with the variation graph.
The new constraint check “Try to change a node to a type while the dimension configuration was also changed” highlights that. Before this PR the test would pass without any errors but it was not able to satisfy
`
Then I expect the node aggregate "new-tethered" to exist
Then I expect this node aggregate to occupy dimension space points [{"language":"de"}]
Then I expect this node aggregate to cover dimension space points [{"language":"de"},{"language":"gsw"}]
`
As neither {"language":"gsw"} nor {"language":"ch"} will be covered.
As a side effect another test in 9.x would fail without adjustment as it mistakenly tests that it _is_ possibly to run a NodeTypeChange on a changed dimension configuration.
Now the test would fail
``` Features/D3-MoveDimensionSpacePoint/MoveDimensionSpacePoint.feature
The dimension space points [{“language”:”ch”}] were not found in the allowed dimension subspace [{“language”:”mul”},{“language”:”de”},{“language”:”en”},{“language”:”gsw”}] ```
because of the the method call
`
NodeTypeChange/NodeTypeChange.php(216): NodeAggregateCommandHandler->requireOrderedOriginDimensionSpacePoints
`
As this is a new limitation by design we now use a simpler NodeProperty migration which is still allowed a passes while dimensions are being changed - still questionable but not as “dangerous”.
Packages:
NeosContentRepository.BehavioralTestsContentRepository.Core
BUGFIX: NodeController improve node resolve exceptions
Nothing big. Just shows also the visibility constraints which could be important.
Packages:
ContentRepository.CoreNeos
BUGFIX: variation coverage restriction
Resolves: #5918
This prefilters the dimension space point set used for variation by evaluating the parent aggregate’s coverage
Review instructions
Check out the new test case
Packages:
NeosContentRepository.Core
BUGFIX: Migrated node variants leak properties from a different dimen…
After migrating a legacy site with content dimensions, a dimension variant shows values from the dimension it was created from, even for properties left empty or never set in that variant. (e.g. an empty or non-existent property in the “en” variant still shows the “de” node after migration.
This happens because creating a node variant copies the whole property set of the other node as source dimension (copyNodeToDimensionSpacePoint); the variant-created events carry no properties of their own. The migration wrote the variant’s own values but never unset the copied-over ones it doesn’t override, so they survive.
It’s not fixed since EventExportProcessor::createNodeVariant() now follows the variant creation with a NodePropertiesWereSet that unsets every property copied from the source which the variant’s own node-data row does not set.
Packages:
NeosContentRepository.Core
BUGFIX: Resolve error when publishing selected changes
### What I did
Change hx-post to hx-get since this is only the first step that only brings up the confirmation dialog. User clicks “Publish selected” → GET confirmPublishSelectedChanges → loads the modal HTML. With the post request the CSRF-Token was missing.
Second problem: When confirming the changes the workspace-module-content is returned to the wrong target. It leads to the content being doubled.
### How I did it
Change POST to GET Method and change the target for the updated workspace-module-content. I basically just adjusted it to how the other buttons work aswell.
fixes https://github.com/neos/neos-development-collection/issues/5895
Packages:
NeosWorkspace.Ui
BUGFIX: Show skipped projections in `cr:setup <https://github.com/neos/neos-development-collection/pull/5899>`_
Before running cr:setup once threw and error and successive runs said
> Content Repository “default” was set up
Now it fetches the status of all subscriptions and thus knows which it will skip.
<img width=”1163” height=”164” alt=”image” src=”https://github.com/user-attachments/assets/87dd29d0-2fb2-49c3-9e50-371b3fe183fd” />
There is no real error handling for this case except a full destruct and replay … for the content graph we anticipate with `#5896 <https://github.com/neos/neos-development-collection/issues/5896>`_but im unsure regarding other subscriptions … maybe we need a new API cli command after all that allows exactly that for one subscription?
The only way currently to escape from this state is by dropping the tables manually and doing the re-setup. The reason why we remember the error state is because any changes done in the setup up until the error were destructive and done without transaction. We dont know where we failed and thus might be fully corrupted.
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.BehavioralTestsContentRepository.Core
TASK: Provide tests for old document uri path projection integer underflow bug
While https://github.com/neos/neos-development-collection/issues/5778 is kindof fixed we have no tests and dont actually know how the scenario came to play. It is definitely not a race condition (https://github.com/neos/neos-development-collection/pull/5788).
As described here https://github.com/neos/neos-development-collection/issues/5778#issuecomment-4797475672 i was able to provoke the old error - when reverting sebs patch - via just two commands. Tag and untag. The untag command must use a greater variant selection strategy than the tag.
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:
Neos
TASK: Improve JSON decode error handling
This change continues what was done in `#5196 <https://github.com/neos/neos-development-collection/issues/5196>`_and contains parts of the closed PR #5093
Packages:
NeosContentRepository.Core
TASK: Allow core developers (me) to use cli tools like `flow setup or others to work and inspect the testing content repository <https://github.com/neos/neos-development-collection/pull/5897>`_
But as the testing cr uses these two tunnel through space factories that know no mercy its impossible.
As this is merely an adjustment in the test fakes there is not much to consider.
Might come in handy to setup the behat testing db initially.
Also with `#5896 <https://github.com/neos/neos-development-collection/issues/5896>`_it definitely comes in handy when using
`
FLOW_CONTEXT=Testing/Behat flow crupgrade:resetgraphandsetup
`
For switching branches with different schemas - which i do a lot - and i always drop the tables by hand — thousand times.
Packages:
NeosContentRepository.TestSuite