Problem/Motivation
Setting the "Published (status)" target against a source (which is tampered as "Convert to Boolean", only alters the default/English language node and leaves the translated node as published.
Steps to reproduce
Preface: it is assumed you have Drupal 9.5.9 installed with all needed language modules set up, and at least 1 additional language installed, with the article content type set to be translatable.
1. Create a new feed type using the "Upload file" fetcher, and "JsonPath" parser, Node processor, and article content type
2. Add the mapping as stated (per the attached JSON example):
- "Published (status)" target to "status" source
- "Published (status)" target to "status" source, configured setting set to French
- "Title (title)" to "title_english"
- "Title (title)" to "title_french", configured setting set to French
- "Body (body): Text" to "type"
3. Context should be set to "$.items.*"
4. Save and edit tamper
- On "status -> Published: value" add "Convert to Boolean" tamper
- Truth set to "Active", False set to "Inactive"
- Submit changes
4. Create new feed based on the type just created.
5. Import items
6. Observe the 2 nodes imported with translations. The item with the "Inactive" status, is still published while english is unpublished
Other steps tried:
1. Setting language on all "Published" targets
2. Only having 1 "Published" target, in hopes it would apply to all
Proposed resolution
If "Published (status)" set as target, feeds should respect the language being set on and update accordingly.
Current workaround/solution is to not allow the published value to be translated so what happens on the default language, persists to the translation.
| Comment | File | Size | Author |
|---|---|---|---|
| #4 | feeds-node-state-3371339-1.patch | 775 bytes | bandana |
| feeds.feed_type.json_import.yml.zip | 1.04 KB | nicole.harnish | |
| test.json_.zip | 669 bytes | nicole.harnish |
Issue fork feeds-3371339
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
nicole.harnish commentedComment #3
waleedagel commentedSame problem.
Comment #4
bandana commentedI think i have the same problem with regular node feeds from csv.
2 languages (default english, secondary swedish), published target (english) to csv source (status_en), published target (swedish) to csv source (status_sv).
On first import all swedish nodes are set to default publishing option for content type. On second import (if values are changed in csv file) all values are as expected.
This patch seems to fix the issue.
Comment #5
bandana commentedComment #6
francismak commentedThank you for this patch. It is working properly. How we tested:
1. Single feed CSV import to Node, English and French, with column TITLE_EN, TITLE_FR, PUBLISHED_EN and PUBLISHED_FR
2. Configure the mapping of all columns, and set the relevant node languages
3. Use 1 for True, 0 for False
4. No tamper plugin used
Be careful when using the tamper plugin "Set value or default value" with "Only if empty" enabled.
It treats 0(zero) as empty.
Comment #7
benstallings commentedClaude Code says, regarding patch #4:
The root cause
Here's the exact sequence that causes the bug. Consider a new node being imported with English status = 0 (unpublished) and French status = 0:
Clear phase (runs first for all mappings):
1. Clear status on base entity → field emptied
2. Clear status on French translation → translation doesn't exist yet, skipped
Set phase:
1. setTarget for English status: array_merge([], [['value' => 0]]) → [['value' => 0]] → unpublished. Correct.
2. setTarget for French status: getEntityTarget() calls addTranslation('fr'), which inherits field values from the base entity — including the just-set status = 0, or potentially the field's default value (status = 1, published). Then: array_merge([['value' => ]], [['value' => 0]]) produces a 2-element array. For a single-cardinality field like status, setValue() takes only the first element — the inherited value wins, the import value is discarded.
The core problem: clearTarget can't clear a translation that doesn't exist yet, but setTarget creates the translation and then merges with its inherited values. The imported value ends up in second position and gets dropped by cardinality enforcement.
Why isNew() is the wrong fix
1. It breaks multi-mapping to the same field on new entities.
Consider two mappings that both target the body field on a new node (e.g., one for summary, one for value, or two sources appending to the same multi-value field):
- Clear phase: field cleared
- Set mapping 1: with isNew() skip → setValue([val1])
- Set mapping 2: with isNew() skip → setValue([val2]) — val1 is lost
Without the patch, the array_merge correctly accumulates: [val1] → [val1, val2].
2. It doesn't fix the same bug on existing entities with new translations.
When an existing entity gets a new translation added during import, isNew() returns FALSE, so the merge still happens and the same value-inheritance problem occurs.
3. isNew() checks the entity, but the problem is the translation.
A new entity and a new translation are different things. The patch conflates them.
What should be done instead
The real fix belongs in the translation creation flow. When getEntityTranslation() creates a new translation via addTranslation(), the inherited values for the target fields should be cleared before setTarget merges with them. Two possible approaches:
Option A: Have clearTarget in the map() method run after translations are created, not before. This is a larger refactor.
Option B: In setTarget(), check whether the field list was actually cleared for this specific entity target. For example, after getting the translation, check if it's newly created and clear the specific target field before merging:
Or most directly: track in getEntityTranslation() whether the translation was just created, and return that information to the caller so it can skip the merge.
Verdict
The bug is real, but this patch introduces a regression for multi-mapping on new entities while only partially fixing the translation issue. I'd reject this specific approach and look for a fix that targets translation-value-inheritance directly.
Comment #8
benstallings commentedComment #10
benstallings commented