Problem/Motivation
I've met "A fatal error occurred: Invalid translation language (und) specified" error when tried to translate entity having paragraphs.
After some debug, I found that this happens because the source language is never set for paragraph translations. And the default source language "und" is used.
There is a special condition to get the error: the paragraph should have a field which have "translation_sync" fields. The only core field that uses the "translation_sync" feature is image.
BTW, if an entity have the only translation, the source language should be set for this translation anyway. I checked how the node module behaves in such case. It sets the translation language as source language. So, if I did not miss something, the "und" is not allowed value for translation source.
STR
1. Create a paragraph with image field having translatable alt and/or title fields.
2. Create a host entity with a paragraph having image with alt/title field filled.
3. Translate the host entity.
Actual result: "A fatal error occurred: Invalid translation language (und) specified."
Proposed resolution
- Set the translation source language if paragraph entity is translatable.
- Extend translation tests: use paragraph bundle with an image field having translatable alt/title fields (fill that fields during transaltion).
Remaining tasks
- write patch
- write/extend tests
- decide if upgrade path required (to set translation source language on existing paragraph entities)
| Comment | File | Size | Author |
|---|---|---|---|
| #35 | translation_source-2597201-35.patch | 4.69 KB | tduong |
| #35 | translation_source-2597201-35-test_only.patch | 3.74 KB | tduong |
| #35 | interdiff-2597201-30-35.txt | 2.52 KB | tduong |
| #34 | translation_source-2597201-34.txt | 9.84 KB | johnchque |
| #30 | translation_source-2597201-30.patch | 3.38 KB | johnchque |
Comments
Comment #2
leksat commentedHere is the patch. Not sure if the approach is good, but it works.
(Unfortunately, I have no time to work on tests)
Comment #4
leksat commentedWrapped content_translation.manager service usage with a try/catch.
Comment #5
leksat commentedComment #6
alexej_d commentedI believe this is related to my issue: Follow-up to #2513226: Test for untranslatable entities before attempt to create a new translation
Comment #7
leksat commented@alexej_d, yeah, I saw this issue, but I thought it's about untranslatable entities. At least it's said in the title :)
In my case, both host node and paragraphs are translatable.
Comment #8
alexej_d commentedYeah, but I have the same error as you "A fatal error occurred: Invalid translation language (und) specified" so I think it could have the same cause :)
Comment #9
miro_dietikerComment #10
tstoecklerVerified that this works. The code looks good as well. I'm not an expert enough to verify that this is the optimal solution to fix the problem but it certainly is a correct way to fix it. The problem - which you have probably figured out already, but noting here for reference - is that
content_translation_entity_presave()asks$manager->getTranslationMetadata($entity)->getSource()for the source langcode and without this added code that ends up beingundwhich then fails as described above.I am still having similar fatal errors when switching the source language of an entity that has paragraphs attached, but I guess that's a separate issue.
Would be great to get this in.
Comment #11
tstoecklerActually since this seems pretty related and touches the same lines of code uploading here, including an interdiff to #4.
I had already wondered about the
isNew()check, not sure why that is needed to be honest. But the added code fixes my use-case of switching the source language. Again, if people think that this is a different problem I'm fine to open a new issue for that. But I thought it might be related. Again, I don't understand the hunk in #4.On a separate note, we should probably fix the try-catch thing. It doesn't seem like it should be needed, very strange that that made the tests work.
Comment #15
killua99 commentedI'll try this patch, we're having problems with translations.
Comment #16
tstoecklerSo maybe to elaborate a bit more: After I had applied #4 I was no longer getting
as an error, but instead
Because now the source language (de) was being set correctly, but the paragraph entities had a different default language than the host entities.
Comment #17
miro_dietikerThis problem was mentioned yesterday on the user group meeting.
To make sure severe errors like this are cleanly handled in the long run, we need test coverage for this!
Comment #18
yobottehg commentedWe also have this error occasionally.
On my experience this happens if you have paragraphs with images and you did not set everything about the image as translatable ( img, alt and title ).
You also have to do this directly on the field itself and not on the translation config page.
Comment #19
tstoecklerHad a problem applying this with #2631590: After previewing an entity with nested paragraphs, EntityChangedConstraintValidator sometimes leaves a node entity un-saveable already applied, so here's a patch for people already having that applied. (Or e.g. people using composer-patches that want to have both.)
Comment #20
michaellenahan commentedI had the following situation:
paragraphs with #4 patch applied (https://www.drupal.org/files/issues/2597201-4.patch)
Multilingual site. Main language German, secondary language English.
A node in German with some paragraphs.
Add an English-language translation to this node (node/N/translations/add/de/en).
Click Save.
Get error:
The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.
Your fix #19 helped, @tstoeckler.
Now I have these patches applied (in this order, using composer-patches):
#16 from https://www.drupal.org/node/2631590#comment-10806858 (https://www.drupal.org/files/issues/2597201-11--vs-2631590-16--do-not-te...)
#19 from @tstoeckler above (https://www.drupal.org/files/issues/2597201-11--vs-2631590-16--do-not-te...)
I am now able to save my DE->EN translations.
Comment #21
michaellenahan commentedEven after #20 I'm still getting this error. The full error with trace is attached: 2597201-21.txt.
Confirming that the problem occurs when an image field needs to be translated. Only paragraphs with translatable image fields appear to be affected by this.
A workaround, if you don't need your image field to be translatable: you can go to Structure > Paragraph Types, edit your paragraph type, find the image field and de-select "Users may translate this field" See Screenshot: 2597201-21.png
Comment #22
killua99 commentedAlso.
RuntimeException: A config mapper can only contain configuration for a single language. in Drupal\config_translation\ConfigNamesMapper->getLangcode() (line 398 of core/modules/config_translation/src/ConfigNamesMapper.php).
Drupal\config_translation\Access\ConfigTranslationOverviewAccess->access(Object, Object)
call_user_func_array(Array, Array)
Drupal\Core\Access\AccessManager->performCheck('config_translation.access.overview', Object)
Drupal\Core\Access\AccessManager->check(Object, Object, NULL, 1)
Drupal\Core\Access\AccessManager->checkNamedRoute('entity.field_config.config_translation_overview.node', Array, Object, 1)
Drupal\Core\Menu\LocalTaskManager->getTasksBuild('entity.field_config.node_field_edit_form', Object)
Drupal\Core\Menu\LocalTaskManager->getLocalTasks('entity.field_config.node_field_edit_form', 0)
Drupal\Core\Menu\Plugin\Block\LocalTasksBlock->build()
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func('Drupal\block\BlockViewBuilder::preRender', Array)
Drupal\Core\Render\Renderer->doRender(Array)
Drupal\Core\Render\Renderer->doRender(Array, )
Drupal\Core\Render\Renderer->render(Array)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1)
__TwigTemplate_edc288ee8347d53b83394ea87e108c7f8bb91488104557c8f9cf0ff5ca68b892->doDisplay(Array, Array)
Twig_Template->displayWithErrorHandling(Array, Array)
Twig_Template->display(Array)
Twig_Template->render(Array)
twig_render_template('core/themes/seven/templates/page.html.twig', Array)
Drupal\Core\Theme\ThemeManager->render('page', Array)
Drupal\Core\Render\Renderer->doRender(Array, )
Drupal\Core\Render\Renderer->render(Array)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1)
__TwigTemplate_d036aeb834ab1c671967ea5be059fcb27a7f054364af6c3e210dbfce42492e38->doDisplay(Array, Array)
Twig_Template->displayWithErrorHandling(Array, Array)
Twig_Template->display(Array)
Twig_Template->render(Array)
twig_render_template('core/themes/classy/templates/layout/html.html.twig', Array)
Drupal\Core\Theme\ThemeManager->render('html', Array)
Drupal\Core\Render\Renderer->doRender(Array, )
Drupal\Core\Render\Renderer->render(Array)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
Comment #23
killua99 commentedAnd thanks, The comment #21 mention to remove the option "users may translate it" and the paragraphs translation start working again.
Comment #24
johnchqueFrom current investigation, it seems that there is a reliable way to detect if we need to update the source languages:
$form_state->getFormObject()->isDefaultFormLangcode($form_state)
Will return TRUE when editing the source. We will also use it to hide the controls intranslation.
Comment #25
tduong commentedOpened a "multilingual workflow bugs only meta issue" #2698239: Multilingual workflow bugs for a "general" discussion for these kind of bugs.
Comment #26
miro_dietikerAnd investigations there turned out that isDefaultFormLangcode() is not reliable during a rebuild. We have found a better way to detect the translation controllers / forms, see the issue referenced by tduong.
Comment #27
miro_dietikerNeeds investigation after the referenced issue.
Comment #28
johnchqueCould reproduce, discussed with @Berdir, this should fix the problem, still need to add tests for it.
Comment #29
loopduplicate commented#28 fixes my problem.
I have node containing a paragraphs field which contains a paragraph field that contains images and textareas. Before the patch, I would get a WSOD and the error, "
Drupal\Core\Entity\EntityStorageException: Invalid translation language (und) specified. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 757 of /Applications/MAMP/htdocs/paragraphs/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).Comment #30
johnchqueAdded tests, let's see what test bot thinks about this.
Comment #31
johnchqueJust tested manually against the latest dev and it seems to be working even without the patch, was this fixed somewhere else?
Comment #32
miro_dietikerFrom discussion with Berdir:
We should have a core issue that fixes the uncaught exception. Core should not die().
Did you really reproduce with a proper translation_sync case?
Comment #33
johnchqueyes, that's true, core should not die.
yes, tested with image field, some days ago I was able to reproduce the fail but not anymore.
Comment #34
johnchqueSeems to be failling since the commit a9810ae. Added diff between that commit and main branch.
Comment #35
tduong commentedIn the test the image field of the Images paragraph type has been not set as translatable. Added missing settings, some checks and comments.
Comment #39
johnchqueTotally true! I knew there was something missing. Thank you @tduong!
Comment #40
miro_dietikerCommitted in attribution of everyone involved. Thx for getting this sorted out! :-)
Comment #43
d0t15t commentedI'm still having this issue when trying to generate content with devel.