Frequently Asked Questions¶
This page collects answers to common questions raised in the ECA support issue queue. Each entry links back to the original discussion for full context.
Tokens and field names¶
How do I reference multi-value field deltas without conflicting with token replacement?¶
ECA's token system uses square brackets ([ and ]) as delimiters. When you
need to target a specific delta in a multi-value field, the traditional Drupal
bracket notation (e.g. field_skills[0][target_id]) clashes with token
replacement.
Use dot notation instead:
1 | |
To use a dynamic delta from a token (e.g. inside a loop), write:
1 | |
This avoids the token system misinterpreting your brackets as token references.
Tip
Dot notation for field deltas is supported in ECA 2.1.x and 3.x.
Original discussion (d.o #3565516)
How do I use literal square brackets in ECA field values?¶
If you need literal square brackets in a value — for example Tailwind CSS
utility classes like [&_.cf-form-label]:tw-hidden or render array keys —
ECA will attempt to replace anything inside [...] as a token.
Workaround: Define two global tokens that output literal brackets:
- Use the "ECA token generate" custom event so the tokens are available site-wide.
- In that event's model, use "Token: set value" to create:
- Token name:
bracket:openwith value[ - Token name:
bracket:closewith value]
- Token name:
- Then use
[bracket:open]and[bracket:close]wherever you need literal brackets.
Since token replacement is not recursive by default, the brackets will be output literally after the first replacement pass.
Original discussion (d.o #3468841)
What does the :value suffix do on tokens?¶
When you use a token like [entity:nid], ECA may return a typed data object
rather than a plain scalar value. If you need the raw value (e.g. to pass an
entity ID as a string to a queue worker or another action), append :value:
1 | |
This is particularly important when forwarding tokens to queue workers or comparing values.
Original discussion (d.o #3545797)
Entities¶
Can I use "Entity: delete" with Paragraphs and other entity types?¶
Yes. The Entity: delete action works with any entity type, not just nodes. This includes Paragraphs, Media, Taxonomy Terms, Users, and custom entity types.
Warning
When triggering entity operations from Drush or cron, the current user is anonymous. Ensure the anonymous role has the necessary permissions, or switch the user context within your ECA model.
Original discussion (d.o #3562153)
How do I load a User entity by username or email?¶
When using Entity: Load with properties, the property values field expects YAML object syntax with curly braces:
1 | |
or:
1 | |
Writing name: "testuser" without the braces will not be parsed correctly.
Original discussion (d.o #3556182)
What does "Defined by token" mean in the "Entity: Load" action?¶
The "Load entity from" dropdown in the "Entity: Load" action has a
"Defined by token" option. This does not mean you provide the entity ID via
a token. Instead, it means the loading mode itself is determined
dynamically by the eca_token_load_entity_from token.
To load an entity by type and ID, select "Entity type and ID" in the dropdown and provide the entity ID in the "Entity ID" field (which supports tokens).
Original discussion (d.o #3550157)
How do I clone a node and modify a field before saving?¶
Use this three-step pattern:
- Entity: clone — creates an unsaved copy of the entity.
- Entity: set field value — modify the field(s) you need to change on the cloned entity.
- Entity: save — persist the modified clone.
This pattern works well with Views Bulk Operations (VBO): select entities in a view, trigger a VBO action, and let ECA handle the clone-modify-save workflow.
Original discussion (d.o #3540136)
Why do I get "Entity: set field value" vs "Entity: get field value" confused?¶
A common mistake when creating a new entity and setting its properties:
- "Entity: set field value" — writes a value to a field. Use this to assign a title, body, or any other field value.
- "Entity: get field value" — reads a value from a field into a token.
When targeting the entity, use the token name you assigned when creating it
(e.g. newpromotion), not the entity type machine name.
Original discussion (d.o #3558803)
Conditions¶
How do I check for multiple user roles?¶
The "User has role(s)" condition allows selecting only a single role. This is by design.
To check for multiple roles (e.g. Manager OR Employee OR Admin), use multiple conditions connected with gateways:
- For OR logic: connect multiple "User has role" conditions to separate branches from an exclusive gateway, each leading to the same action.
- For AND logic: chain conditions as successors so all must pass before the action executes.
Tip
See the Combined Conditions library model for a working example of AND/OR condition patterns.
Original discussion (d.o #3558514)
How do I check if a value is contained in a list of values?¶
If you need to check whether the current node's ID is in a specific list of
IDs (similar to an "IN" operator), use the "Compare two scalar values"
condition with the contains operator:
- Value 1:
,26122,26119,26567,(the list, wrapped with leading and trailing commas) - Value 2:
,[node:id],(the value to find, also wrapped in commas) - Operator:
contains
The leading and trailing commas prevent false positives (e.g. ID 261
matching inside 26122).
Note
The eca_list_contains condition is designed for token-based lists, not
inline comma-separated values. For hardcoded lists, the scalar comparison
approach above is more reliable.
Original discussion (d.o #3556083)
Forms¶
How do I populate a multi-value entity reference field?¶
The approach depends on the widget type and timing:
- On form build (before the user sees the form):
- Use "Form field: set default value" with just the entity ID.
- After an Ajax event (e.g. after user interaction):
- Use "Form field: set value" with the format
Entity Name (ID)for autocomplete widgets.
For multiple values, use a loop with a delta counter and dot notation:
1 2 | |
Tip
Tags-style, Select, and Checkboxes widgets accept multiple values more easily than the single-value Autocomplete widget. Consider switching the widget type if multi-value population is a core requirement.
Original discussion (d.o #3565511)
How do I distinguish "Add more" Ajax clicks from real form submissions?¶
The form validation event fires for every form submission, including when a user clicks "Add another item" on a multi-value field. To distinguish real form saves from Ajax requests:
Check the [entity:nid] token immediately after the submission event. If
the entity has not been saved yet (because it is an Ajax request rather than a
real save), the NID will not be available. Use this to skip validation logic
during "Add more" clicks.
Original discussion (d.o #3564434)
How do I add a custom submit button and handle its click?¶
Adding a custom button (e.g. "Cancel") requires two separate events:
- "Build form" event — use the "Form: Add Submit Button" action to add the button to the form.
- "Form submit" event — use the "Form: Compare Triggered Submission" condition to detect which button was clicked.
Warning
Use the "Build form" event, not "After Build form", to add the button. The "After Build" event fires too late for button additions.
Original discussion (d.o #3539759)
Events and redirects¶
Why does my redirect not work with the "Response created" event?¶
The "Response created" (kernel.response) event fires after Drupal has
already started building the response. At that point, it is too late to
replace the response with a redirect.
Use the "Controller found to handle request" (kernel.controller) event
instead. This event fires early enough for the "Redirect to URL" action to
take effect.
Note
The kernel.response event still works for modifying response headers or
for handling 403/404 error pages, because in those cases the response is
being built differently.
Original discussion (d.o #3566396)
Can I prevent entity deletion from a pre-delete event?¶
No. By the time the pre-delete event fires, Drupal is already committed to the delete operation. Only throwing an exception would stop it, which is not a clean approach.
Alternative: Use access control to conditionally hide the delete link. For example, use the "ECA Views Field" action with the "Views field" event: evaluate each entity row in a View to determine whether deletion should be allowed, and show or hide the delete link accordingly.
Original discussion (d.o #3537710)
How do I use "Views: Set filter value" with "Views: Execute query"?¶
These two actions cannot be chained sequentially. ECA is event-driven: when you execute a View via the "Views: Execute query" action, Drupal dispatches the "Views: Pre Build" event for that View.
Create a separate event listener for the "Views: Pre Build" event and use "Views: Set filter value" there. This way, the filter is applied automatically whenever the View is built — whether triggered by your "Execute query" action or by any other mechanism.
Tip
Use the filter_id value matching the machine name of the exposed filter
field in your View configuration.
Original discussion (d.o #3488727)
Queue tasks¶
How do I pass data to a queue worker?¶
When using the "Enqueue task" action, do not use the task_value field to
pass entity IDs or other data. Instead:
- Use the "Tokens to forward" field — enter the token name (without
brackets), e.g.
prelim_nid. - That token will be available in the queue worker model under the same name.
- For entity field values, use the
:valuesuffix to get the raw scalar value:[entity:nid:value]rather than[entity:nid].
Warning
Queue workers run as the anonymous user. Ensure the anonymous role has the necessary permissions to load and manipulate the entities your worker needs to access.
Original discussion (d.o #3545797)
Workflow and content moderation¶
Why does the workflow transition event not fire on re-publishing?¶
When a content-moderated entity is published, moved to draft, and then
published again, the "Workflow: state transition" event may not recognise
the second transition. This is a
known Drupal core bug
where $entity->original loads the latest default revision instead of the
latest revision, making the from/to states appear identical.
Workaround: Apply the patch from Drupal core issue #3346430 or the community-provided ECA patch from the discussion linked below. This issue is also documented in the Troubleshooting page.
Original discussion (d.o #3417834)
Upgrading¶
How do I upgrade from ECA 2.x to 3.x?¶
When upgrading ECA and its modeler modules (e.g. bpmn_io) to version 3.x, you must follow the ECA 3.0.0 release notes upgrade procedure. ECA 3 includes update scripts that enable the required new modules.
Danger
Do not upgrade bpmn_io to 3.x without also upgrading ECA to 3.x. The
modeler depends on services that moved in the ECA 3.x architecture
(e.g. modeler_api.service), and upgrading one without the other will
cause fatal errors.