9.1.6 (2026-06-22)
Overview of merged pull requests
BUGFIX: UTC `recordedAt optional event migration <https://github.com/neos/neos-development-collection/pull/5858>`_
Optional migration to adjust event time stamps and node dates to UTC https://github.com/neos/neos-development-collection/pull/5716
By storing “recordedAt” as datetime field we lost its original timezone information. But we can make the assumption that its timezone should be the same as the one encoded in the ATOM metadata field “initiatingTimeStamp”
The migration first groups all events by the ATOM offset found in “initiatingTimeStamp”. If all events are UTC “+00:00” the migration is not necessary. For all non UTC groups we convert the “recordedAt” datetime field to the datetime in the UTC timezone.
The migration must not be executed multiple times as it would remove the offset to match UTC again for the “recordedAt” datetime even if they are already meant to be UTC. To prevent this from happening we compare the “recordedAt” and “initiatingTimeStamp” and if they are equal considering timezones we know the migration was run.
Packages:
NeosContentRepositoryRegistry
BUGFIX: Fix timeable node visibility inheritance
./flow timeablenodevisibility:execute now does not try to enable disabled nodes that are only disabled because of inheritance.
resolved: https://github.com/neos/neos-development-collection/issues/5876
Upgrade instructions
Review instructions
x 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:
TimeableNodeVisibility
BUGFIX: Provide `./flow subscription:catchUpActive to invoke a manual catchup <https://github.com/neos/neos-development-collection/pull/5863>`_
In the past year i shared a snippet on slack a few times which allowed to trigger a manual catchup. This is not intended to be required to use but we cannot rule out the possibility:
> Allows explicit manual invocation for recovery
> All modifications via ContentRepository::handle() already trigger a catchup internally
> It cannot be 100% guaranteed that the commited events are catchup as they are two transactions by design
> A lost database connection or killed PHP process can result in the event-store being ahead.
Now the introduction of the subscription engine `#5321 <https://github.com/neos/neos-development-collection/issues/5321>`_christian and me agreed on a simpler easier to use api instead of the technical _correct_ api. That turns out not to help though. So here it is.
Also with the new locking `#5852 <https://github.com/neos/neos-development-collection/issues/5852>`_we can run into the theoretical problem that a process wants to do an catchup but a simulated publishing might be blocking it for too long which means no catchup is done.
The code people previously had to use ^^
```php public function catchUpActiveCommand(string $contentRepository = ‘default’): void {
- $subscriptionEngineAccessor = new class implements ContentRepositoryServiceFactoryInterface {
public SubscriptionEngine|null $subscriptionEngine; public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface {
$this->subscriptionEngine = $serviceFactoryDependencies->subscriptionEngine; return new class implements ContentRepositoryServiceInterface { };
}
}; $this-contentRepositoryRegistry->buildService(ContentRepositoryId::fromString($contentRepository), $subscriptionEngineAccessor); $subscriptionEngine = $subscriptionEngineAccessor->subscriptionEngine; $subscriptionEngine->catchUpActive();
}
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
BUGFIX: Parallel workspace creation corrupts content graph
Fixes: https://github.com/neos/neos-development-collection/issues/5591
Introduce failing test for parallel workspace creation
> Integrity constraint violation: 1062 Duplicate entry ‘w-1780989485’ for key ‘PRIMARY’’
related https://github.com/neos/neos-development-collection/issues/5058
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.BehavioralTestsContentRepository.Core
BUGFIX: Ensure `Node::$timestamps uses UTC format consistently instead server timezone <https://github.com/neos/neos-development-collection/pull/5716>`_
Requires https://github.com/neos/eventstore-doctrineadapter/pull/29
In the database we cant persist the timezone but only the date. ~And DBAL seems to automatically store them in UTC which makes sense.~ In DBAL we use Doctrine\\DBAL\\Types\\DateTimeImmutableType::convertToDatabaseValue() which invokes only ->format for the date as Y-m-d H:i:s.
Now the date comes from https://github.com/neos/neos-development-collection/blob/c1a329f3a3f9e6c36e83484cf3d90d345a8e2169/Neos.ContentRepositoryRegistry/Classes/Factory/Clock/SystemClock.php#L15 (or the FakeClock)
And is written into the recordedat column of the event: https://github.com/neos/eventstore-doctrineadapter/blob/e7d35402e05280be82794fbe507062d0e6cf48e0/src/DoctrineEventStore.php#L304
Either we must ensure we use only UTC dates or we change the date to UTC in the event store.
Then we can merge this change which ensures that during deserializing we always use UTC and never ask the system date_default_timezone_get () as this should be irrelevant.
Upgrade instructions
With the change https://github.com/neos/neos-development-collection/pull/5858 a new kind of migration tooling will be provided to upgrade Neos projects: Content repository upgrades.
These upgrades are available via crupgrade and contain for example like in the Neos 9 beta phase tooling to adjust and correct your events.
In the case of this UTC change if your server was previously configured in local PHP time and you consider the recordedAt dates really important for legal reasons in example, you can choose to fix these.
This is a fully optimal migration and which can also be executed once your upgrading to a next minor version like 9.2
`
./flow crupgrade:eventsrecordedattoutc
`
Packages:
ContentRepository.Core
BUGFIX: Update to neos eventstore v2 (part 1)
Adjust to new
WithResetInterfaceAdjust to moved
InMemoryEventStoreand new mandatory argument
The actual bugfix will be done in corporation with https://github.com/neos/neos-development-collection/pull/5716
Packages:
NeosContentRepository.Core
BUGFIX: Add migration to fix json column types in neos_contentrepository_domain_model_nodedata
Adds a missing migration for Neos 8.4 with PGSQL.
Renames the doctrine type comments to flow_json_array. I’ve choosen a random version number after latest migration in 8.4 but before any possible migration version of newer versions. This shall ensure the right order.
We can discuss if we need this in 8.3 already. But I think 8.4 shoud be fine.
Test will be provided via #5611
Packages:
Neos
BUGFIX: Add custom rendering for hidden document nodes in preview mode
Renders a dedicted screen for a document which is hidden but requested in preview mode.
Fixes: #5724
<img width=”2054” height=”1589” alt=”image” src=”https://github.com/user-attachments/assets/7d6295a1-e5ee-4a6d-90ea-8d34f33a9804” />
Packages:
Neos
BUGFIX: restore ugly int string `NodeAggregateIds indexes <https://github.com/neos/neos-development-collection/pull/5854>`_
unreleased regression from https://github.com/neos/neos-development-collection/pull/5727
thanks bsc for spotting ;)
see slack
https://neos-project.slack.com/archives/C04PYL8H3/p1780681254601739
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.Core
BUGFIX: Neos.Neos:Site add label and icon
Required for the Neos.Neos/Inspector/Editors/LinkEditor when specifying
``` linking:
- linkTypes:
- Node:
startingPoint: ‘/<Neos.Neos:Sites>’
instead of just /<Neos.Neos:Sites>/my-site
As this allows the sites node to be shown in the Ui then :)
Packages:
Neos
BUGFIX: Implement global advisory lock for CR
This avoid race conditions during simulation and subscription updates. We are locking a bit too much at this point, but it is at least safe this way. In theory simulations should be possible in parallel but for now we want to prevent this.
Packages:
NeosContentRepository.Dbal
Revert “BUGFIX: Prevent unnecessary `updateContentStreamVersion() updates within transaction simulation” <https://github.com/neos/neos-development-collection/pull/5851>`_
Reverts #5838
Superseded by a global lock #5852
Packages:
TimeableNodeVisibilityContentGraph.DoctrineDbalAdapterContentRepository.Core
BUGFIX: NodeDuplication filters properties to write
FIXES: #5686
Packages:
Neos
BUGFIX: Failed subscription does not contain full stack-trace logged in database
$error->getTraceAsString() does not include the important line and file where the error actually happened now but only information of the lines and files before
Also the previous error if any was not logged.
Upgrade instructions
Packages:
NeosContentRepository.Core
BUGFIX: PostgreSQL compatible TrashBin projection
Requires 9.0 https://github.com/neos/neos-development-collection/pull/5790 to run PostgreSQL in CI
Carefully extracted from https://github.com/neos/neos-development-collection/pull/5751
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:
NeosWorkspace.Ui
BUGFIX: Handle numeric node aggregate ids when building `NodeAggregates <https://github.com/neos/neos-development-collection/pull/5727>`_
Currently by not restricting numeric values like "132" in the NodeAggregateId validation we allow it. Yet the behaviour is utterly broken due to us being tricked by phps “feature” which converts numeric strings to integers when using it as array index. We often put node ids into a hashmap but get integers back and then fail recreating a node aggregate id and other funky cases. I hope i found all cases…
Type error: Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId::fromString(): Argument `#1 <https://github.com/neos/neos-development-collection/issues/1>`_($value) must be of type string, int given, called in Packages/Neos/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php on line 290
A classic one thanks due to phps type casting for numeric array keys :)
$array[‘123’] will be stored as int 123 and not accessible via "123"
Additionally the SubtreeTags - pained by a similar bug - are now restricted to be never fully numeric. See discussion in Slack: https://neos-project.slack.com/archives/C04PYL8H3/p1767965980113829
At some point phpstan might be able to detect all cases for once and for all: https://phpstan.org/blog/why-array-string-keys-are-not-type-safe
Upgrade instructions
Packages:
NeosContentRepository.Core
BUGFIX: Use Node instead of Document in linkTypes reference
The key needs to be Node, as in the example in that section. Just the headline and copy were wrong.
Review instructions
Hope this covers all places that would need to be adjusted.
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: PostgreSQL compatibility for `Neos.Neos - no graph <https://github.com/neos/neos-development-collection/pull/5790>`_
Carefully extracted from `#5751 <https://github.com/neos/neos-development-collection/issues/5751>`_and reduced to the essential changes to ease reviewing
The CI tests now postgreSQL compatibility by running all tables in postgres except the content graph which runs in mariadb
Needs followup change for 9.1 which turns the new `#5542 <https://github.com/neos/neos-development-collection/issues/5542>`_projection postgresql compatible -> https://github.com/neos/neos-development-collection/pull/5805
TODO:
- [x] add composer script to run m*sql vs postgresql tests, see match in github ci
- [x] remove obsolete @contentrepository and @adapters= tags in behat -> #5806
- [x] ~review AbstractSubscriptionEngineTestCase::resetDatabase -> simplify with https://github.com/neos/neos-development-collection/pull/5802~ -> not easy
- [x] reduce ci runs to a sane default currently we test mysql / mariadb / postgresql version with different php version 8.2-8.5 but it might make more sense to rather test the minimum supported mysql with the lowest php and maximum mysql with newest php instead all combinations
like with testing mysql 8.0 we want to run postgreSQL only with php 8.4 in the matrix.
Later
- [ ] document min postgresql version? 16 for any_value?
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
[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
[x] Reviewer - Breaking Changes are marked with
!!!and have upgrade-instructions
Packages:
Neos
BUGFIX: Recover from unexpected error during command simulation
Adds automatic recovery for the problem described in https://github.com/neos/neos-development-collection/issues/5713 where content streams are left closed
Invocations to $this->contentRepositoryProjection->apply() which are part of $commandSimulator->handle() and thus the $handle function might throw any DBAL exception if something went wrong. For example when the transaction died due to a lock. The actual transaction is rolled back via withSimulation() but we also need to commit a new event that undos the previous closing.
You might think locking - e.g. closing and reopening - must not be done in this way as a fatal connection crash or the php process dying would still not recover from that but for this `#5827 <https://github.com/neos/neos-development-collection/issues/5827>`_solves it for the future.
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.Core
BUGFIX: Prevent unnecessary `updateContentStreamVersion() updates within transaction simulation <https://github.com/neos/neos-development-collection/pull/5838>`_
… depending on the database setup this can cause conflicts.
A local database with low latency does pass the parallel tests but mariadb docker-virtualised runs already slower and might fail - also in CI:
``` Class: Doctrine\DBAL\Exception\LockWaitTimeoutException Message: An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction Code: 1205 File: Packages/Libraries/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php Line: 44
… #4 <https://github.com/neos/neos-development-collection/issues/4>`_Packages/Neos/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Projection/Feature/ContentStream.php(62): Doctrine\DBAL\Connection->update(‘cr_test_paralle…’, Array, Array) … ``
For a full description of the error see https://github.com/neos/neos-development-collection/issues/5713#issuecomment-4519261505
Review instructions
This change was part of the experiments in https://github.com/neos/neos-development-collection/pull/5825
And becomes especially relevant for 9.2 - the layers - where there is more load on this method - probably because forking will be too fast:)
See https://github.com/neos/neos-development-collection/pull/5776 and WorkspacePublicationDuringWriting test
Implementation detail: The new introduced state on the DoctrineDbalContentGraphProjection is not something i like to keep forever thus i have already prepared a refactoring - but this change is kept minimal to prevent it from being delayed: https://github.com/neos/neos-development-collection/pull/5837
Packages:
NeosContentGraph.DoctrineDbalAdapterContentRepository.Core
TASK: Enforce proper sequence during parallelism for MariaDB 12
Replaces https://github.com/neos/neos-development-collection/pull/5885
With the new introduction of MariaDB 12 it reports for the test WorkspacePublicationDuringWritingTest
> Got exception DriverException: An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1020 Record has changed since last read in table ‘cr_test_parallel_p_graph_contentstream’
which is true and probably a sane limitation from Maria. This seems to underline that #5869 <https://github.com/neos/neos-development-collection/issues/5869>`_will be required. So as done for the ``PublishingDuringPublishingTest` we can and should also limit the parallelism in CI and find out how we can also do this safely for production Neos’ #5870
Packages:
NeosContentRepository.BehavioralTests
TASK: Update Fusion documentation to reflect MenuItemState usage
Fixes: #5732
Packages:
.githubFusion.AfxNeos
TASK: Fix migrations for MariaDB 12.x
What I did
Some old Flow migrations dropped foreign keys by their hardcoded auto-generated names (e.g. …_ibfk_1). These names are no longer reliable: on MariaDB 12+, renaming a table no longer renames its auto-generated foreign key/index names along with it, so the constraint names the migrations expect may not exist and the migrations fail.
Instead of relying on hardcoded constraint names, the affected migrations now look up the actual foreign keys on the table via the schema manager and drop the one defined on the relevant column. This works regardless of what the constraint is actually named, making the migrations compatible with MySQL, MariaDB < 12 and MariaDB ≥ 12 alike.
Why the CI change
Until now this breakage went unnoticed because the pipeline never executed the Doctrine migrations. The build workflow now runs ./flow doctrine:migrate before the functional tests, so the full migration chain is verified on every build.
Depends on: #5853
Also depending on: https://github.com/neos/flow-development-collection/pull/3571
Packages:
Neos
TASK: Fix typos and grammar mistakes in documentation
Hi!
I tried to fix as many typos and grammar mistakes as I could (within reasonable time). There are still many other mistakes but I needed to call it done. I used cspell, Claude and regular expressions (\\b(\\w+)\\s\\1\\b) to find them. Note that I did not use Claude to generate new text.
Upgrade instructions
n/a
Review instructions
I picked 9.2 as the base (not 8.3, as instructed) simply because that’s where I started working before coming across that requirement. I also didn’t generate the docs because I assume that is done by your pipeline. Please let me know if I should cherry-pick my changes to an 8.3 based branch.
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:
Fusion.AfxMediaNeos
TASK: Overhaul CI jobs to support multiple databases and parallel execution
This refactors the CI pipeline and splits the jobs to allow them to run in parallel. Also it enables us to test more database servers and versions.
Packages:
Neos.github
TASK: Disable new global cr advisory lock by default
Followup to https://github.com/neos/neos-development-collection/pull/5852
Adds experimentalContentRepositoryLock as configuration option - for us - it does not work fully yet.
See
https://github.com/neos/neos-development-collection/issues/5869
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.DbalContentRepositoryRegistry
TASK: Correctly use virtual objects in yaml
Before https://github.com/neos/flow-development-collection/pull/3576 flow threw
> Object configuration for argument “2” contains neither object name nor factory object or method name in configuration of package Neos.Http.Factories, definition for object “Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory”
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: Provide parallel tests attempting to replicate deadlocks
In https://github.com/neos/neos-development-collection/pull/5510 i attempted to cause a locking problem manually and see how the subscription engine reacts.
(see slack)
Now these tests are actual parallel tests were we thought we could replicate the problem of a ContentStreamWasForked event failing. But instead it showed another problem,
Adds a new test PublishingDuringPublishingTest which fails on 9.0
> Doctrine\DBAL\Exception\DeadlockException: An exception occurred while executing a query: SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
Upgrade instructions
Packages:
NeosContentRepository.BehavioralTests
TASK: Run projection integrity violation detection after every scenario to assert integrity
solves: https://github.com/neos/neos-development-collection/issues/5795
requires https://github.com/neos/neos-development-collection/pull/5807 requires https://github.com/neos/neos-development-collection/pull/5798 requires https://github.com/neos/neos-development-collection/pull/5820
Now we run the ProjectionIntegrityViolationDetection after every scenario to assert integrity
This is done via Behat Hooks to avoid specifying the line every time which is verbose and can be forgotten.
Before the integrity was only checked after dimension adjustments though as outlined in `#5795 <https://github.com/neos/neos-development-collection/issues/5795>`_two regular tests lead to a faulty integrity.
Also this change becomes relevant with new adapters on rise postgresql `#5751 <https://github.com/neos/neos-development-collection/issues/5751>``_and for big m*sql graph refactoring like ``#5776 <https://github.com/neos/neos-development-collection/issues/5776>`_so that we are sure integrity is always provided.
Packages:
NeosContentRepository.TestSuite
TASK: Extend 5790
Rolls back some unnecessary test code handling
instead provides consistent column naming and types in feature file
linting
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.DbalNeos