Replicator Field Blink Cache Issue in Event Listener
Bug description
I have an Event Listener that is called on the EntrySaved $event. I grab the freshly saved entry, go over it and populate all the used fields in my custom array. I don't rely on $entry->get() because it did not work for my use case with localization.
I get the available fields from the blueprint of the entry:
$blueprint = $entry->blueprint();
$fields = $blueprint->fields()->toPublishArray();
I then loop over the fields, check if data is set in the entry and add it to my data array. While doing this, i resolve association fields, grid fields, asset fields and replicator fields.
I started with grid fields and had no problems with association fields inside the grid field. But since we are talking like 20 Rows of grids i converted them to replicator because we need to be able to collapse.
After that change, the problem started
Workflow:
I open my collection and save it -> my array is populated correctly
I save again (Without leaving or reload) -> all the associations in my replicator fields are now suddenly completely ignored and return null if i get them via $entry->{$field_handle};
This led me to the believe, that this is a caching issue. I tried to find out where Blink is interefering etc. but since documentation is really rare for this, i just tested some things.
In the end the only solution that worked was calling Blink::flush(); before processing the entry. Then it populated them correctly again.
When i was debugging i also noticed, that this seems to be related to filling the Relation Entry with the wrong parent. (using multisite feature). And that is the reason that it then can't find the Relation in the entry itself, because this is the original one.
How to reproduce
Not sure if this is easily reproducable. I think the following criteria have to be met:
- Multisite
- Having a entry that is connected with another language
- Replicator field with relation field inside
Logs
Environment
Environment
Application Name: App Name
Laravel Version: 12.40.2
PHP Version: 8.2.29
Composer Version: 2.9.2
Environment: local
Debug Mode: ENABLED
URL: statamic.local
Maintenance Mode: OFF
Timezone: UTC
Locale: en
Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED
Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single
Mail: smtp
Queue: sync
Session: file
Storage
public/storage: NOT LINKED
Statamic
Addons: 0
Sites: 2 (App Name, App Name Spanish)
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 5.69.0 PRO
Installation
Fresh statamic/statamic site via CLI
Additional details
No response
Probably related: https://github.com/statamic/ssg/issues/171
I observed similar behavior in the static site generator since all the caching optimizations we’re introduced in Statamic V5, and it wasn’t consistently reproducible. The only workaround was the same one you suggested: flushing blink. It would probably be better to identify and fix the underlying root cause.
For me it is reproducable in my setup and only happens with relations inside replicator fields. If someone can point me in the right direction where to check the Blink Cache generation for that, i maybe could dig deeper myself.
I tried to pin down the problem for my usecase with the help of Claude.ai. We tested the fix, and it is working. I give you the summary:
Bug: In multisite, replicator relationship fields resolve to the wrong locale on subsequent saves in the CP (without a page reload). First save is correct; second save returns relationships from a different locale. Flushing Blink between saves avoids it.
Steps to Reproduce (generic):
- In a multisite site, edit a localized entry that has a replicator set containing a relationship/entries field.
- Save once → relationships resolve correctly in the current locale.
- Without reloading, save again (or switch locales in the same session and save). The relationship now resolves to another locale or comes back null.
- Blink::flush() before the second save prevents the wrong-locale resolution.
Observed Behavior:
- On the second save, EntriesFieldtype::queryBuilder() resolves site_resolved to the previous locale because the parent locale is stale in the cached replicator Fields.
- Root cause: Replicator::fields() caches Fields instances via Blink::once() using a key that omits locale/parent context, so the cache is reused across locales and carries the first locale’s parent. Relationship field augmentation then localizes to that stale locale.
Relevant Source:
- vendor/statamic/cms/src/Fieldtypes/Replicator.php::fields() (Blink key missing locale/parent).
- vendor/statamic/cms/src/Fieldtypes/Entries.php::queryBuilder() (uses parent locale to pick site).
Fix Applied Locally (verified): Include locale and parent id in the Blink key to prevent cross-locale reuse:
$parent = $this->field()->parent();
$locale = $parent && method_exists($parent, 'locale')
? $parent->locale()
: Site::current()->handle();
$parentId = $parent && method_exists($parent, 'id') ? $parent->id() : null;
$hash = md5($this->field->fieldPathPrefix().$index.json_encode($config).$locale.$parentId);
After this change, saving twice keeps relationships in the correct locale without flushing Blink.
Suggested Upstream Fix: Adjust Replicator::fields() (and review other Blink caches like Fields::toPublishArray()) to include locale/parent context in cache keys so cached Fields instances aren’t reused across locales.
I am of course not sure, if this would break other things. But in my mind this is just something that was forgotten / overlooked when implementing cache. There are also places where site identifier is used in cache code and places, where it is not.
I hope this was helpful!