Problem/Motivation
Migrate Drupal UI reports the wrong version of Drupal under certain conditions.
Steps to reproduce
In the Migrate Drupal UI screen, if you select Drupal 6 or 7 as the source site, but enter credentials to the current Drupal 10 site, you get this message:

The code in question is checking the Drupal version by reading the key_value table from the provided database credentials entered, which in my Drupal 10 beta site is the following:

As such, the error is correctly triggered, but the wrong version is reported.
This is probably a very rare case, but the error message is confusing and should report the correct version of Drupal (even if this was a mistake).
Proposed resolution
Report the correct version of Drupal, or change the error message to say something along the lines of the version of Drupal detected was newer than 6 or 7, please check your database credentials for the old version and try again (so its more ambiguous).
Remaining tasks
see #21
User interface changes
New error message if the source db is the same as the destination db

API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | array values not identical.png | 68.37 KB | akhil babu |
| #28 | Screenshot 2024-01-29 at 20-13-05 Drupal Upgrade dev1-web.png | 27.21 KB | quietone |
| #25 | source-db-same-as-target-not-working-ddev.png | 107.82 KB | akhil babu |
| #25 | source-site-new-error.png | 83.55 KB | akhil babu |
| #17 | d9 shows d8 in key_value table.png | 324.07 KB | akhil babu |
Issue fork drupal-3323990
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:
- 3323990-migrate-drupal-reports
changes, plain diff MR !5813
Comments
Comment #2
quietone commentedI tested with a Drupal 10 source database and the version displayed was '1'. Attached is a fix for that.
Regarding the situation in the issue summary, as pointed out this is working as designed. The only source of data is the source database and the only way to to figure out the version is the value for the system_scheme. Not sure why the Drupal 10 site shows a Drupal 8 schema.
Comment #3
quietone commentedComment #5
quietone commentedI guess we could add some tests on the version string. Maybe this will do.
Comment #6
smustgrave commentedCC failure in #5
Comment #7
quietone commentedThat's odd. Anyway updated patch. No interdiff because this is so small.
Comment #8
smustgrave commentedI pointed my migration setup to a 11.x branch and got this error
Source database is Drupal version 1 but version 7 was selected.
Applying the patch I get
Source database is Drupal version 10 but version 7 was selected.
Which I believe is correct as the 11.x branch guess is D10.
So issue seems to be resolved with the patch in #7
Also ran the test without the fix and got
Failed asserting that two strings are identical.
Expected :'10'
Actual :'1'
Which was the same as my manual test.
Comment #10
smustgrave commentedUnrelated failure.
Comment #12
smustgrave commentedRandom failure
Comment #13
catchI think this could use a comment.
Comment #14
akhil babuPatch #7 fixes the error message when connectng to drupal 10 site.
But connecting to drupal 9 site still shows incorrect error message. Error message is "Source database is Drupal version 8 but version 7 was selected." instead of "Source database is Drupal version 8 but version 7 was selected."
I tested it in Drupal 9.5.11. As mentioned in the IS, drupal checks key_value table in source database to determine drupal version of source site.
Output of this query for the D9 site is i:8901; Ideally output should have been in the format "i:9xxxx"(For D10 site, its i:10100; ).
Is there any other table that we can use to get the drupal version?
Comment #15
quietone commentedI have converted to an MR and added a comment per #13. It really does need a comment and I should have done it when I wrote that.
@Akhil Babu, Are you sure that is a Drupal 9 site? Did all the database upgrades run successfully?
Comment #17
akhil babuYes. I tried with a fresh d9 site. Also tried installing the site using drush as well as from the UI. In both cases, value getting stored in the table is

i:8901;Comment #18
mikelutzWould it be easier to just change it to say 'Drupal version 8 or later' if we don't explicitly detect 6 or 7? The migrate UI is only designed for 6 or 7, so it doesn't much matter that we accurately find out the specific version, only that we accurately determine if it's 6 or 7, or something we don't handle.
Comment #20
benjifisher@mikelutz and I discussed this issue at #3410291: [meeting] Migrate Meeting 2023-12-21 1400Z. We agree that getting the Drupal version from the schema version is unreliable. What we should really do is check for the common mistake and give a really specific error message in that case. Otherwise, say something like "it is not a D7 database" instead of trying to say what version it is.
Closely related to how unreliable it is to use the schema version: I confirmed what @Akhil Babu pointed out in Comment #17. With a fresh install of Drupal 9.5.11, the schema version is
8901. I think it would be different if I had started with an earlier version of Drupal 9 and upgraded to 9.5.11 (depending on which earlier version). But for migrations, a clean install is an important use case.Let's go back and start again. I am setting the issue status back to NW.
Comment #21
quietone commentedI removed everything related to trying to use the schema in key_value to get the Drupal version for D8+. If the source database is a Drupal 8+ database the error message will be, "Source database does not contain a recognizable Drupal version.". That is not the best error message so that needs work.
I also added a check if the source database is the same as the site database. If that is the case then the error message is "Source database is the same as the site database."
Comment #22
quietone commented@benjifisher, thanks for the review. I have replied to your comments and this is in better shape now.
Comment #23
smustgrave commentedThink benjifisher should do the re-review here.
Comment #24
smustgrave commentedComment #25
akhil babuI've tested the latest changes.

Using drupal 9/10 sites as the source now throws the new error message "Source database does not contain a recognizable Drupal version."
But the error displayed was still 'Source database does not contain a recognizable Drupal version' when the current site's credentials were given as the credentials for the target site. According to the new change, it should be 'Enter credentials for the source database, not the target database.'
The following condition was failing because the output of
$connection->getConnectionOptions()andDatabase::getConnectionInfo()['default']were different.Tested on Drupal 11, on a ddev-based setup. For ddev, the Database host, Database name, Database username, and Database password will be "db".
Comment #26
akhil babuComment #27
benjifisher@Akhil Babu:
Thanks for catching that!
Instead of
we should probably use
I tested this using both MariaDB and SQLite.
Comment #28
quietone commentedUnfortunately, Strict comparison can't be used here. As mentioned in the MR the array key order is not guaranteed to be that same. And the screenshots from #25 also show that the arrays have different values even for the same db. Therefor, I have reworked the logic to compare a subset of the connection options.
I also looked more closed at the new error message and compared it with the existing language. For example, the Overview page uses old site and new site. Because of that I changed the message. I hope it is an improvement.
Comment #29
akhil babuThanks for updating @quietone
I think strict comparison should be removed from the new logic as well. The ‘port’ key in the datatable is causing the condition to fail due to type mismatch.
Comment #30
akhil babuComment #31
quietone commented@Akhil Babu, thanks for the feedback. In the future, when reporting testing results it is good practice to include the steps you took.
I did some manual testing and found that it is rather easy to have the port number a string in one case and a number in the other. I use ddev and ddev sets the port as a number but the example in settings.php is to use a string. Therefor I added an array_map to cast each element to string.
Comment #32
quietone commentedI am not sure why this was causing errors in some Drupal 6 Upgrade tests but the fix is to remove a change I made early when working on this.
Comment #33
benjifisherIn the test function:
And in the data provider:
I am not sure whether it is required or just good practice, but when mocking a method with an optional parameter, we explicitly provide the parameter. The existing test case for D9 does this:
'system'andTRUEare the parameters fortableExists(), andFALSEis the result. We should use the same pattern for D10.Since the MR removes the call
$connection->schema()->tableExists('key_value')ingetLegacyDrupalVersion(), we should remove the lines with'key_value'from the data provider and add an assertion thattableExists()is not called with'key_value'. Or there is probably a simpler way to get the same result. (We do not really need a map if we know that the method is always called once.)I think it is a little simpler to use
array_intersect_key():More importantly, the list of options has to depend on the driver. If the driver is
sqlite, then I think onlydatabase(the filename) andprefixmatter. Ifportorhostare supplied, then (I think) they are ignored. We should adddriverand/ornamespaceto the list of options. Formysql,portis optional: leaving it unset is the same as setting it to3306. I am not sure about PostgreSQL.It is tempting to use
$connection->createUrlFromConnectionOptions(), but that is marked asand
getConnectionInfoAsUrl()only works if we have a key in the$databasesarray. It is so close to being easy, but it is not!Comment #34
quietone commented@benjifisher, thanks for reviewing!
1,2,3 Fixed
4. While it does depend on the driver, the keys that are not used will be filtered out, so we just need the maximum sensible set of keys. So, when I tested with sqlite the arrays being compared only had the 'database' and 'prefix' keys. Adding 'driver' is problematic because you have say 'mysql' and 'Drupal\mysql\Driver\Database\mysql', the later being produced from the CredentialForm. That is why I had a change earlier to strip that to just the driver name. That could be added back. See https://git.drupalcode.org/project/drupal/-/merge_requests/5813#note_246068
Comment #35
smustgrave commentedSeems to need a rebase.
Small discussion in #d11readiness we are holding the subtree split for the book module because of #3421015: Convert MigrateDestination plugin discovery to attributes which is postponed on this one so hopefully can land soon.
There's also 1 other book ticket unrelated we are also waiting on.
Comment #36
quietone commentedThis issue is not a blocker. [#/3421015] is blocked on #3424509: Update MigratePluginManager to include both attribute and annotation class which is waiting for reviews.
I have rebased. The only conflict was removing phpstan-baseline.neon. This is passing commit-code-check locally but fails on gitlabci.
Comment #37
quietone commentedComment #38
smustgrave commented@quietone thanks for clarifying in #36.
Looking at the MR I see the 1 thread open, from what I can tell, has been addressed.
The changes look good, unless there is anything else needed for this?
Comment #39
benjifisherSorry, March has been a bit crazy for me.
Thanks for updating
MigrationConfigurationTraitTest. I like the newwillReturn()bits a lot better.I have one suggestion for
CredentialFormTest. See the MR. Back to NW for that.As we discussed in today's migration meeting, let's add a follow-up issue to simplify
getLegacyDrupalVersion()further. Copying my suggestions from there:tryblock.$version_stringand then returning it at the end.
Comment #40
quietone commentedTagging for the followup.
Comment #41
smustgrave commentedOpened #3437178: Simplify getLegacyDrupalVersion()
Appears rest of feedback has been addressed
Comment #42
catchCommitted/pushed to 11.x and cherry-picked to 10.3.x, thanks!
Comment #45
catchCrosspost issues...