Drupal - How to migrate multilingual image alt fields from CSV?

I think I've figured this out. You need to define the 'content_translation_source' property on the translated node, so that Drupal knows what language it's coming from.

Eg:

migrate_plus.migration.articles_fr.yml

process:
  #...
  content_translation_source:
    plugin: default_value
    default_value: en
  #...

(Be sure to substitute the value en for whatever language you've first imported content -- the example in the OP uses English, but this might be anything).


I was asked how I figured this out:

I'm the guy who got multilingual migrations into D8 core, so I do know a bit about the matter :)

In this case, I used xdebug and put a breakpoint where the exception was thrown (ContentEntityBase.php line 745). It looked weird that it was using 'und' as the langcode, rather than 'en'—so I looked up the call stack to see where that was coming from. It turns out to be from content_translation_entity_presave(), which runs:

$source_langcode = !$entity->original->hasTranslation($langcode) ? $manager->getTranslationMetadata($entity)->getSource() : NULL;

In this case $manager->getTranslationMetadata($entity)->getSource() is basically equivalent to $entity->content_translation_source->value.

I wondered, why would that yield 'und'? I checked what happens when I translate an entity in the browser, and in that case it gives me 'en'. Something must be setting the source language! Indeed, ContentTranslationHandler::entityFormEntityBuild() calls setSource() when we're translating in-browser.

So, I figured I would just replicate that behaviour in the migration, by setting content_translation_source in the process. This also explains why D6 -> D8 migration of translations work, since d6_node_translation.yml has content_translation_source in the process.