Here is the error displayed when trying to access a "manage fields" page on any content type:

Uncaught PHP Exception RuntimeException: "A config mapper can only contain configuration for a single language." at /.../d8_test/core/modules/config_translation/src/ConfigNamesMapper.php line 399

To reproduce on a clean install:
- Install drupal with a different language than english
- Add two languages.
- Enable the 'Configuration Translation' module
- Try to access /admin/structure/types/manage/article/fields

Here are some variables values just before the exception.

$langcodes = Array ( [0] => fr [1] => en );
$this->pluginId = node_type;
$this->pluginDefinition = Array (
  [title] => type de contenu,
  [names] => Array ( [0] => node.type.article, [1] => core.base_field_override.node.article.title ),
  [weight] => 10,
  [class] => Drupal\node\ConfigTranslation\NodeTypeMapper,
  [base_route_name] => entity.node_type.edit_form,
  [entity_type] => node_type
);
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

idflood created an issue. See original summary.

idflood’s picture

Issue summary: View changes
idflood’s picture

Here is a simplytest.me instance which reproduce the issue: https://dfvk7.ply.st/

idflood’s picture

Priority: Normal » Major

Bumping to major since this make the "manage fields" screen unusable and it triggers a PHP error ( https://www.drupal.org/core/issue-priority#major-bug )

jakow’s picture

I've got the same problem at the Drupal-8 rc1

RuntimeException: A config mapper can only contain configuration for a single language. in Drupal\config_translation\ConfigNamesMapper->getLangcode() (line 399 of core/modules/config_translation/src/ConfigNamesMapper.php).

Devbuddha’s picture

I have the same Problem with Drupal-8-rc1. With Beta 15 it was ok.

RuntimeException: A config mapper can only contain configuration for a single language. in Drupal\config_translation\ConfigNamesMapper->getLangcode() (line 399 of core/modules/config_translation/src/ConfigNamesMapper.php).

jakow’s picture

...so there is no support for multilingual configuration with config_translation module?

mdespeuilles’s picture

I have the same problem on 3 different sites. With beta 15 and beta 16 it was ok..

claudiu.cristea’s picture

I followed the steps from IS but I cannot reproduce the error. Just before the first step, I enabled the 'language' module.

What other condition needs to be triggered?

idflood’s picture

I tried again and one extra requirement is to install drupal with a different language than english. When I tried again with english as the install language there was no error.

I was still able to reproduce the issue with the latest dev version and french as the install language.

idflood’s picture

Issue summary: View changes
C-Logemann’s picture

I can also confirm this error on actual dev version with using german as installation language and adding two other languages later.

C-Logemann’s picture

I made a test with commenting the exception line:
// throw new \RuntimeException('A config mapper can only contain configuration for a single language.');
Now the config page was loaded. But with removing the comment it seems the config page is still working.
This is maybe helpful for others to find the real problem.

claudiu.cristea’s picture

Priority: Major » Critical
Status: Active » Needs review
Issue tags: +D8MI
FileSize
3.11 KB
1.8 KB

Thank you all, for finding this bug. Attached a "test only" patch to prove the bug and a fix.

I'm not sure about the solution from the patch. This needs review from the multilingual initiative team. Tagging accordingly. Also I see this a s another Critical.

swentel’s picture

+++ b/core/modules/config_translation/src/Tests/ConfigTranslationNonEnglishSiteTest.php
@@ -0,0 +1,53 @@
+  /**
+   * {@inheritdoc}
+   */
+  protected $profile = 'standard';
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['language'];

Can't we use minimal and enable language, locale and config translation here ?

claudiu.cristea’s picture

@swentel, sorry, I cannot reproduce the error outside 'standard'. For sure, I'm missing something. And, looking in the failed phpunit test, I'm convinced my solution is not the right solution. Someone from D8MI should look into this.

dawehner’s picture

Also wrote a test which reproduces exactly the issue summary

claudiu.cristea’s picture

@dawehner, yes, but it doesn't necessary occur when installing the site with other language. I tested manually. I installed with EN and setup later other language as default. It gives the same failure. My "test only" patch from #14 proved that.

claudiu.cristea’s picture

Status: Needs work » Needs review
dawehner’s picture

Well, this is the general problem we have, we start with trying to fix the problem, without writing the tests first. The idea of the regression test is to have different level of regression protection, and well, installing with a different language is quite a total valid usecase.

tstoeckler’s picture

Assigned: Unassigned » tstoeckler

Will take a look at this.

tstoeckler’s picture

So I will try to debug this locally a bit, but it seems that this is in fact the "correct" fix, after #2212069: Non-English Drupal sites get default configuration in English, edited in English, originals not actually used if translated. The original idea of this code was that shipped configuration is generally in English, but the referenced issue changed the semantics of that assumption.

tstoeckler’s picture

So I will try to debug this locally a bit, but it seems that this is in fact the "correct" fix, after #2212069: Non-English Drupal sites get default configuration in English, edited in English, originals not actually used if translated. The original idea of this code was that shipped configuration is generally in English, but the referenced issue changed the semantics of that assumption.

claudiu.cristea’s picture

@tstoeckler, by "correct fix" you mean defaulting to site default language?

tstoeckler’s picture

Re #29: Yes, that is what I meant.

In studying the code more in-depth, however, I wondered why we even reach that fallback anyway. I.e. all configuration should always have a language code explicitly, thus the fallback (whether it be to en or to the site's default language) should be theoretical only at least in core. It's there as a safeguard for contrib and custom modules, that forget to set a language code.

In looking at that in more detail I found that the problem is that since #2571337: Node type title label cannot be translated in the UI NodeTypeMapper adds core.base_field_override.node.$node_type.title to the list of config names even if that config object does not exist. And weirdly $config_factory->get($name)->get('langcode') simply returns NULL without throwing an error which is why we then reach the fallback.

Interestingly the "non-existing config name" leads to a problem (an undefined index notice, to be precise) in ConfigTranslationFormBase as well but that is explicitly worked around in NodeTypeTranslationTest by adding the core.base_field_override.node.$node_type.title specifically. This was hard to catch in #2571337: Node type title label cannot be translated in the UI because the test code was being moved.

Removing that line makes that notice appear in the test. Then also making NodeTypeTranslationTest install Drupal in a different language then makes the exception described in the issue summary appear. This is what I provided now as a sort of "minimal" regression test.

The actual fix of the "symptom" is to only include the core.base_field_override.node.$node_type.title config name in NodeTypeMapper if it exists. That is what I have done in the patch. It is very strange that ConfigFactory has no exists() or has() method, which is why I had to go with the loadMultiple(). Another way would be if (!$this->configFactory->get($name)->isNew()) but that seems even more bizarre to me.

Per the above I still think because of #2212069: Non-English Drupal sites get default configuration in English, edited in English, originals not actually used if translated the patch in #14 is a valid bug fix because there will be contrib or custom modules that do actually miss a langcode key in their config but because this is marked critical I think we should aim for the most "direct" fix of the symptom here. I will open a separate issue for the patch in #14 hoping that I'm not stepping on your toes @claudiu.cristea. Really great detective work figuring that out in the first place! Note that the above is not an endorsement of this issue's critical status, I'm just accepting that as an a priori state.

Because this bug is effectively caused by #2571337: Node type title label cannot be translated in the UI maintainers might want to instead revert that first and include the fix here when re-opening that one. (I'm not suggesting that that issue should or should not be reverted, I'm just anticipating that this will be brought up.) Because of other recent fixes in Config Translation we should make sure that tests are green with a revert of that issue before doing that, though, so I will upload a patch that does just that in the next comment.

Also found a small amount of dead code in WebTestBase when debugging this will open a separate issue for that, as well.

tstoeckler’s picture

git revert e16b2b08a7ff6f655ca8e5a2339a2bef021decd6

If this is green and the revert is favored by maintainers, probably doing the revert locally is preferred instead of committing this in patch form.

tstoeckler’s picture

Status: Needs work » Needs review
Related issues: +#2571337: Node type title label cannot be translated in the UI

Yeah, PhpStorm's autosave is a really awesome feature. Sorry for the borked patch, this is the real revert patch.

Opened #2589589: ConfigNamesMapper::getLangcode() should fallback to the site's default language not 'en' in the meantime.

tstoeckler’s picture

Status: Needs work » Needs review
Issue tags: +language-config, +sprint
FileSize
7.44 KB

Ahhh

tstoeckler’s picture

Assigned: tstoeckler » Unassigned
claudiu.cristea’s picture

I would add also the @dawehner's test from #19. I don't think we have in core a regression test for non-English site install.

Gábor Hojtsy’s picture

I think the fix in #30 makes most sense. I would personally do a get()->isNew(), makes it more apparent what you are doing IMHO, that seems to be intent of the API to use for existence check. Also while I did not agree with the premise of #2589589: ConfigNamesMapper::getLangcode() should fallback to the site's default language not 'en' I think we can reformulate it for locale module with a different goal. Let's continue that there.

Gábor Hojtsy’s picture

Status: Needs review » Needs work

Looking more at #2589589: ConfigNamesMapper::getLangcode() should fallback to the site's default language not 'en', seems like we not only need to check if the config name exists, but should pre-check if it has the same langcode as the mapper so as to not set up an impossible situation for config translation where the sources may be multiple languages and we cannot ensure to translate them to a single language.

alexpott’s picture

Status: Needs work » Needs review
FileSize
1.39 KB
4.17 KB

FWIW I consider the behaviour of ConfigFactory::get() for non existing configuration objects a mistake. There should be a separate ::create() method for this. But @Gábor Hojtsy is correct that the isNew() method is often used to determine existence.

Gábor Hojtsy’s picture

So as I said in #44, we not only need to check if the config exists, but that it uses the same langcode as the existing config in the mapper. I think addConfigName() may be a good place to check this. With the current setup, addConfigName() blindly adds the name and then once the mapper is attempted to be used, it throws the exception. Only adding the config if it exists does not really solve the fact that the two config files may be in different languages, which is why the PHP fatal was thrown.

Gábor Hojtsy’s picture

Assigned: Unassigned » alexpott

I believe @alexpott is working on an update, so assigning to him.

tstoeckler’s picture

FWIW, I disagree with #46. As discussed in IRC with @GáborHojtsy regardless of what we do, we cannot actually prevent having config files associated to the same mapper in different languages (which prevents translation). If we only add the file to the mapper if the langcodes match we have a sort of "silent failing" in that (in this case) you cannot translate the node type label (because the respective file is not added to the mapper) but you get absolutely no feedback that something is wrong or why it is. I don't think that is a very good idea.

Instead I think we should "fail gracefully" by catching the exception in the UI and notifying the user about this in some way. The details should be discussed in a follow-up issue I guess but I imageine something like:
- Still show the translate tabs and everything (and make sure that no fatals bubble up, i.e. catch the exception)
- On the translation overview show a drupal_set_message(..., 'warning') with something like

The configuration files related to the node type Article have different source language codes and thus cannot be translated:

  • node.type.article: Spanish
  • core.base_field_override.node.title.article: Hungarian

We could do other things as well, ideas could be:
- Show some suggestion on how to fix this (maybe link to d.o)
- Fix this automatically somehow
- Present a UI to choose which langcode to set for all the config files
- Still allow to translate some of the config files for which the langcode matches (and still show a warning)
...

Again, I think that should be discussed in a follow-up, but I don't think silently failing is a good idea. In other words I consider #45 to be RTBC material perhaps plus the test from #19 per #42.

Gábor Hojtsy’s picture

Yeah we can get the fix in now for the immediate problem and make adjustments so the more specific problem does not happen. The more specific problem with the langcode may appear and may become critical if people reproduce it though, but we can handle that as its own issue (critical if need be).

lokapujya’s picture

Is a condition of the problem that the installed language does not have a translation?

Gábor Hojtsy’s picture

@lokapujya: no, the config file would be in a specific language regardless of translation availability.

Gábor Hojtsy’s picture

Ok here is the fix from #45 plus test from #19 to see how it fairs with tests and reviews :) Hopefully did not step on @alexpott's toe, tried to reach him today a few times but was unable to.

alexpott’s picture

Yep I'm flying to BADCamp today... I've been working on a fix but I really hate the way it is going - I agree with @tstoeckler let's do a minimal fix here to fix the problem we know we have and then open a followup to examine what else we might need to do. I consider #52 as rtbc'able too.

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Yay, looks like we are in agreement. Fix/test looks good for this scope. I did not write neither the test nor the fix, just uploaded a compound patch, so I should be eligible to RTBC. :)

The last submitted patch, 31: 2584603--revert-2571337.patch, failed testing.

The last submitted patch, 14: 2584603-14.patch, failed testing.

The last submitted patch, 14: 2584603-test-only.patch, failed testing.

The last submitted patch, 19: 2584603-14.patch, failed testing.

The last submitted patch, 30: 2584603-30--tests-only_.patch, failed testing.

kattekrab’s picture

Manual test with simplytest me, following the steps outlined in the IS.

Against head, and with the patch in #52

When hitting /admin/structure/types/manage/article/fields HEAD says

"The website encountered an unexpected error. Please try again later."

and with the patch we see the manage fields page.

RTBC from me too. Screenshots attached.

C-Logemann’s picture

I did a manual test again with #52 patch and can also confirm that the error is gone. So RTBC from me too.

YesCT’s picture

opened #2595535: Show helpful message (do not fatal!) when configuration files have different source language codes and cannot be translated

will need clarification in the issue summary, and maybe adjusting of the priority and category.

nicrodgers’s picture

Tiny update on the patch from #52 to correct a typo.

alexpott’s picture

Assigned: alexpott » Unassigned

Doesn't need to be assigned to me.

  • catch committed 766c154 on 8.0.x
    Issue #2584603 by tstoeckler, claudiu.cristea, alexpott, nicrodgers,...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Added the three people who tested manually to the commit credit.

Committed/pushed to 8.0.x, thanks!

Juan Duarte’s picture

The same error while trying create a content type in a bilingual site and #52 patch work for me. Thanks

juanse254’s picture

This patch led to another error described here as a follow up #2598232: ConfigFactory::get() pollutes ::loadMultiple() static cache with new config objects.

Gábor Hojtsy’s picture

Issue tags: -sprint

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

a.milkovsky’s picture

I still can see exception at /admin/structure/types/manage/page/fields/node.page.body
If you still have the exception even after Drupal update:

  1. comment out "throw new \RuntimeException('A config m..." in the mentioned line
  2. resave field form
  3. uncomment the exception

P.S. Drupal 8.0.0-rc3

EdizonTN’s picture

Upgrade to Drupal 8 RC4.
It's working correctly.

ndvo’s picture

I am having this error when adding an existing field to a new content type.

The content types were created when the default language of the site was English. The default language was changed. When adding an existing field to another content type I get the error. Also, of course, when trying to edit the field.

Drupal 8.0.2

EdizonTN’s picture

Yeah,

I confirm. Problem shows again:

The website encountered an unexpected error. Please try again later.

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 8.0.2 multilanguage

ptmkenny’s picture

Status: Closed (fixed) » Needs work

Also getting the same issue on 8.0.2 with two languages enabled. I did change the default language of the site from English to Japanese after creating a few pieces of content, but the error is arising from "Manage Fields" for a content type that I created after enabling the Japanese language and setting it as the default.

Re-opening because two other people (#73 and #74) are also experiencing this problem on 8.0.2.

swentel’s picture

There's another issue for this somewhere, please don't reopen old issues.

Will link to it later

Gábor Hojtsy’s picture

pierregermain’s picture

I have this problem when changing the the Label of the Title of a Content Type.

Workaround: I found that when you translate for the first time a title of a Content Type you can't use strange characters. So the first time do use only [A-Z] chars.

golddragon007’s picture

Status: Closed (fixed) » Active

Hi, I get this with the 8.0.3 D8 (and with the 8.0.2 too, I only updated from 8.0.2 to 8.0.3).
RuntimeException: A config mapper can only contain configuration for a single language. in Drupal\config_translation\ConfigNamesMapper->getLangcode() (line 400 of \core\modules\config_translation\src\ConfigNamesMapper.php).

Debug:

    $config_factory = $this->configFactory;
    $langcodes = array_map(function($name) use ($config_factory) {
      // Default to English if no language code was provided in the file.
      // Although it is a best practice to include a language code, if the
      // developer did not think about a multilingual use-case, we fall back
      // on assuming the file is English.
      watchdog_exception('debug', new \Exception("A"), "Error1: %test", array("%test" => var_export($config_factory->get($name)->get('langcode'), true)));
      return $config_factory->get($name)->get('langcode') ?: 'en';
    }, $this->getConfigNames());
    watchdog_exception('debug', new \Exception("A"), "Error2: %test", array("%test" => var_export($langcodes, true)));
    watchdog_exception('debug', new \Exception("A"), "Error3: %test", array("%test" => var_export($this->getConfigNames(), true)));
    if (count(array_unique($langcodes)) > 1) {
      throw new \RuntimeException('A config mapper can only contain configuration for a single language.');
    }

Watchdog log:
Error1: 'sk'
Error1: 'en'
Error2: array ( 0 => 'sk', 1 => 'en', )
Error3: array ( 0 => 'node.type.page', 1 => 'core.base_field_override.node.page.title', )

I tried to reproduce with a newly installed Drupal 8, but it wasn't successful.

Some basic information about the site:
There're 6 languages including with the English (which is not the default language, and basically it's not used, but it's not turned off). All internationalization module is turned on. I did a lot of things, before I detected this, so I don't know what caused this. :(

I get this when I go to /admin/structure/types/manage/page/fields . (editing the default two content type's [basic page, article] fields) With custom content type, I don't get any error, it works well.

swentel’s picture

Status: Active » Closed (fixed)