I have a fairly simple D6->D8 migration, and I need a custom source plugin for one of my node migrations. As far as I can tell, I have everything written and structured properly, but when I click on the migration group in the admin UI, I get a message that my source plugin doesn't exist.

Here's the relevant part of my node migration config:

In /my-module/config/install/migrate_plus.migration.video.yml:

id: video
label: Video
  - Drupal 6
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
migration_group: node
  plugin: mrctvVideoSource
  node_type: video

and my source plugin in /my_module/src/Plugin/migrate/source/mrctvVideoSource.php:

namespace Drupal\migrate_mrctv\Plugin\migrate\source;

use Drupal\migrate\Plugin\migrate\source\SqlBase;
use Drupal\migrate\Row;

 * Source plugin for MRCTV video nodes.
class mrctvVideoSource extends SqlBase {

   * @MigrateSource(
   *   id = "mrctvVideoSource"
   * )
  public function query() {
    return $this->select('view_videos', 'vv')
                ->fields('vv', array_keys($this->fields()));

   * {@inheritdoc}
  public function fields() {
    $fields = [
      'video_data' => $this->t('Video Data'),
      'thumbnail_data' => $this->t('Thumbnail Data'),
      'show_ads' => $this->t('Show Ads'),
      'raw_s3_file' => $this->t('Raw S3 File'),
      'nid' => $this->t('Node ID'),
      'vid' => $this->t('Version ID'),
      'title' => $this->t('Nond Title'),
      'node_created' => $this->t('Created'),
      'node_changed' => $this->t('Changed'),
      'node_uid' => $this->t('Node User'),
      'node_body' => $this->t('Body'),
      'teaser' => $this->t('Teaser'),
      'revsion_uid' => $this->t('Revision UID'),
      'log' => $this->t('Revision Log'),
      'timestamp' => $this->t('Revision Timestamp'),

    return $fields;

From what I can tell, I have everything named and annotated properly and in the correct locations, but I'm obviously missing something. What is it?


UPDATE: Per Mike Ryans'suggestion below, I changed the id of my plugin (after clearing cache) from 'mrctvVideoSource' to 'mrctv_video_source', both in the migration yml file and the id annotation in my plugin definition (is there anywhere else I need to change it?). But now, after uninstalling my module (and having to manually delete the config records in the config database again, config_devel doesn't seem to be clearing anything out), my node migrations are not even listed on the Migration page. Sigh. Still troubleshooting...


Obvious question - did you rebuild cache (drush cr)?

The only odd thing I see is having a mixed-case plugin ID - what if you made it all lower-case?

  • So just to make sure, does the plugin ID in the migration config match with just the file name of the source plugin? Or the id value in the annotation? Or both? – wonder95 Dec 7 '16 at 17:28
  • OK, apparently you can't have camel case migration ID values (which makes no sense to me). I changed the migration ID from mrctvVideoSource to mrctv_video_source, and after fighting with enabling/disabling the module a few times, my migrations are showing now. – wonder95 Dec 8 '16 at 16:35
  • The plugin ID in the configuration file must match the ID defined in the annotation. The filename for your plugin class must match your plugin class name. The standard conventions are that the class name is CamelCase while plugin IDs are underscore_separated_lowercase. I was not aware that the plugin ID convention was enforced, and I can't see it documented anywhere, it just struck me as the one out-of-the-ordinary aspect of your code. – Mike Ryan Dec 8 '16 at 22:03
  • Yeah, apparently it is enforced. I'll document it, if you want to point me to the correct page. – wonder95 Dec 8 '16 at 22:05
  • I'd say drupal.org/docs/8/api/plugin-api/annotations-based-plugins - interestingly, though, it has a mixed-case example, which is still in core, so it seems like mixed-case does actually work? – Mike Ryan Dec 9 '16 at 19:47

I think you need to have your annotation outside of the class

 * Source plugin for MRCTV video nodes.
 * @MigrateSource(
 *   id = "mrctvVideoSource"
 * )
class mrctvVideoSource extends SqlBase {

I had a similar PluginNotFoundException for my custom source plugin today. It turned out that during a faulty configuration merge (via git) and the following configuration import my migration plugin got deactivated.

My migration group was still showing up in the Migrate UI because i was using a drush config-import after every change in the fieldmapping:

drush config-import --partial --source="modules/my_migration/config/install"

Because I basically hid the symptoms of a disabled module with the config-import, it took me some time to find the real problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.