Page MenuHomePhabricator

Fatal exception on Special:MovePage: "Failed to create null revision while moving page ID"
Open, MediumPublicPRODUCTION ERROR

Description

Trying to move a page on English Wikipedia resulted in an internal error:

[XaalggpAIC4AAJFHVOwAAACG] 2019-10-16 05:07:15: Fatal exception of type "MWException"

However, the move later went successfully.

Reproduction steps

  1. Go to https://commons.wikimedia.beta.wmflabs.org/wiki/Special:Preferences#mw-prefsection-gadgets
  2. Enable LuckyRename (slightly changed from the version currently used on production enwiki to trigger this bug)
  3. Go to any file page.
  4. Rename it using LuckyRename. See https://en.wikipedia.org/wiki/User:Alexis_Jazz/LuckyRename for info. Feel free to +1 the last number of https://commons.wikimedia.beta.wmflabs.org/wiki/File:76f2dbef4cc9_26_100.jpg.

Details

Request ID
XaalggpAIC4AAJFHVOwAAACG
Request URL
/w/index.php?title=Special:MovePage&action=submit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Aklapper set Request URL to /w/index.php?title=Special:MovePage&action=submit.Oct 17 2019, 4:14 PM
Aklapper set Request ID to XaalggpAIC4AAJFHVOwAAACG.
Aklapper edited Stack Trace. (Show Details)

Had one of these crop up in 1.35.0-wmf.23:

reqId: Xmlp4ApAAEIAAEOHaLsAAABA

/w/index.php?title=Especial:Reanomena&action=submit   MWException from line 836 of /srv/mediawiki/php-1.35.0-wmf.23/includes/MovePage.php: Failed to create null revision while moving page ID 123 to Foo
#0 /srv/mediawiki/php-1.35.0-wmf.23/includes/MovePage.php(531): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.35.0-wmf.23/includes/MovePage.php(374): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.35.0-wmf.23/includes/specials/SpecialMovepage.php(627): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.35.0-wmf.23/includes/specials/SpecialMovepage.php(135): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.35.0-wmf.23/includes/specialpage/SpecialPage.php(575): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.35.0-wmf.23/includes/specialpage/SpecialPageFactory.php(621): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.35.0-wmf.23/includes/MediaWiki.php(299): MediaWiki\SpecialPage\SpecialPageFactory->executePath(Title, RequestContext)
#7 /srv/mediawiki/php-1.35.0-wmf.23/includes/MediaWiki.php(972): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.35.0-wmf.23/includes/MediaWiki.php(535): MediaWiki->main()
#9 /srv/mediawiki/php-1.35.0-wmf.23/index.php(47): MediaWiki->run()
#10 /srv/mediawiki/w/index.php(3): require(string)
#11 {main}

One occurrence from 1.35.0-wmf.38 when trying to move page ID 59470806 to https://en.wikipedia.org/wiki/Category:2019–20_UEFA_Champions_League_participants_seasons

/srv/mediawiki/php-1.35.0-wmf.38/includes/MovePage.php:888

Failed to create null revision while moving page ID 59470806 to Category:2019–20_UEFA_Champions_League_participants_seasons
t exception.trace 	
	#0 /srv/mediawiki/php-1.35.0-wmf.38/includes/MovePage.php(569): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.35.0-wmf.38/includes/MovePage.php(379): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.35.0-wmf.38/includes/api/ApiMove.php(194): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-1.35.0-wmf.38/includes/api/ApiMove.php(91): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-1.35.0-wmf.38/includes/api/ApiMain.php(1585): ApiMove->execute()
#5 /srv/mediawiki/php-1.35.0-wmf.38/includes/api/ApiMain.php(525): ApiMain->executeAction()
#6 /srv/mediawiki/php-1.35.0-wmf.38/includes/api/ApiMain.php(496): ApiMain->executeActionWithErrorHandling()
#7 /srv/mediawiki/php-1.35.0-wmf.38/api.php(84): ApiMain->execute()
#8 /srv/mediawiki/w/api.php(3): require(string)
#9 {main}

Seen again on 1.35.0-wmf.39 while promoting group2

exception.trace
#0 /srv/mediawiki/php-1.35.0-wmf.39/includes/MovePage.php(569): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.35.0-wmf.39/includes/MovePage.php(379): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.35.0-wmf.39/includes/api/ApiMove.php(194): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-1.35.0-wmf.39/includes/api/ApiMove.php(91): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-1.35.0-wmf.39/includes/api/ApiMain.php(1585): ApiMove->execute()
#5 /srv/mediawiki/php-1.35.0-wmf.39/includes/api/ApiMain.php(525): ApiMain->executeAction()
#6 /srv/mediawiki/php-1.35.0-wmf.39/includes/api/ApiMain.php(496): ApiMain->executeActionWithErrorHandling()
#7 /srv/mediawiki/php-1.35.0-wmf.39/api.php(89): ApiMain->execute()
#8 /srv/mediawiki/php-1.35.0-wmf.39/api.php(44): wfApiMain()
#9 /srv/mediawiki/w/api.php(3): require(string)
#10 {main}

RevisionStore::newNullRevision() is documented to return RevisionRecord or null on failure. This failure happens either because the locking of the page table row failed or retrieving the latest revision from the master database. It normally resolves itself on second try, so maybe user facing exception is misplaced here. I could remember when I reported this, I just clicked the button again and it went successfully. Also looking at the 1.35.0-wmf.38
occurrence, (T235589#6267815), it can be seen the page was moved on retry and the null revision created (it's a bot user actually). As far as I can see, there's no report where the move page failed despite retries or where the move succeeded but the page failed to contain the null entry eventually.

The 1.35.0-wmf.23 (T235589#5962211) and 1.35.0-wmf.39 ( T235589#6272772) reports do not have link to see but I believe both succeeded on retry. I looked at other places (WMF-deployed) where null revision is created to see how they handle the possible null. All, but one, are not throwing user exception.

  1. During page protection we create null revision with the method from RevisionStore. WikiPage::doUpdateRestrictions() is what updates the log, and it checks for this null. If it founds the null revision was not created it just outputs a normal user error using Status object. We actually have a message for that case: MediaWiki:no-null-revision
  1. During import we create null revision. The revision creation lives in ImportReporter::reportPage(). It wraps the whole log creation and other logic inside if ( $nullRevRecord !== null ) and does nothing else if it happens to return null.
  1. In the file system, LocalFile.php does the same thing as ImporterHelper, it just wraps everything inside if ( $nullRevRecord ). It does nothing if otherwise.
  1. FlaggedRevs extension does not care at all. It even uses the result (that might be null) to directly call RevisionStore::insertRevisionOn() which is typehinted to accept only RevisionRecord.
  1. FileImporter is the only caller of the method that throws exception. It intercepts the null and throws ImportException. Then later catch the exception, log error and rethrow it. I found one such exception occurrence in T164729: NullRevisionCreator.php: Failed to create null revision (2017), they updated Title::getArticleID() at the time to use Title::GAID_FOR_UPDATE flag. (IDBAccessObject::READ_LATEST now), and it seems the exception never occurred since then (per Phabricator search)

If these places, Protection, Import, File, etc were also throwing exception I believe we would have seen more of this kind of report, since the null is bound to happen occasionally, until such time when the RevisionStore method is refactored to guarantee that it returns revision record in all cases.

So I believe this will continue to happen here and there, it cannot simply go away as long as RevisionStore::newNullRevision() can return null. I believe we should replace the exception with normal user error (like how protection does it). Once a user retries, the chances are it will work.

Ammarpad triaged this task as Medium priority.

Change 609570 had a related patch set uploaded (by Ammarpad; owner: Ammarpad):
[mediawiki/core@master] Add extra details to error log to debug why null revision creation is failing

https://gerrit.wikimedia.org/r/609570

Seen again on 1.36.0-wmf.2 on Commons:

MWException from line 905 of /srv/mediawiki/php-1.36.0-wmf.2/includes/MovePage.php: Failed to create null revision while moving page ID 92702621 to File:Ancienne_église_de_Laborde_(Hautes-Pyrénées)_2.jpg

Change 609570 merged by jenkins-bot:
[mediawiki/core@master] Add extra details to error log to debug why null revision creation is failing

https://gerrit.wikimedia.org/r/609570

I will call this closed. In case it happen again, the error message will hopefully be a little more informative than it used to be and can be tracked in a new task.

thcipriani added a subscriber: thcipriani.

Reopening since we use the task ID to track in logstash. This is still happening although the message has changed a bit. 225 times in 30 days:

Example:
ReqID: YCOC0jTBsMxjFfgbLAbFNAAAARU
Message: MWException: Failed to create null revision while moving page ID ## to XXXXXX (page ID #)
Stacktrace:

from /srv/mediawiki/php-1.36.0-wmf.27/includes/MovePage.php(935)
#0 /srv/mediawiki/php-1.36.0-wmf.27/includes/MovePage.php(589): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.36.0-wmf.27/includes/MovePage.php(435): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.36.0-wmf.27/includes/specials/SpecialMovepage.php(718): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.36.0-wmf.27/includes/specials/SpecialMovepage.php(204): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.36.0-wmf.27/includes/specialpage/SpecialPage.php(645): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.36.0-wmf.27/includes/specialpage/SpecialPageFactory.php(1405): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.36.0-wmf.27/includes/MediaWiki.php(310): MediaWiki\SpecialPage\SpecialPageFactory->executePath(Title, RequestContext)
#7 /srv/mediawiki/php-1.36.0-wmf.27/includes/MediaWiki.php(944): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.36.0-wmf.27/includes/MediaWiki.php(548): MediaWiki->main()
#9 /srv/mediawiki/php-1.36.0-wmf.27/index.php(53): MediaWiki->run()
#10 /srv/mediawiki/php-1.36.0-wmf.27/index.php(46): wfIndexMain()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}
Ammarpad removed Ammarpad as the assignee of this task.EditedFeb 10 2021, 5:31 PM

Reopening since we use the task ID to track in logstash. This is still happening although the message has changed a bit. 225 times in 30 days:

Example:
ReqID: YCOC0jTBsMxjFfgbLAbFNAAAARU
Message: MWException: Failed to create null revision while moving page ID ###### to XXXXXX (page ID #####)

I guess the ##### are integers, can you post them here?. I want to know if they are equal

Krinkle renamed this task from Fatal exception on Special:MovePage: "Failed to create null revision while moving page ID 123 to Draft:Foo" to Fatal exception on Special:MovePage: "Failed to create null revision while moving page ID".Jun 24 2021, 9:43 PM
Krinkle added subscribers: AlexisJazz, Krinkle.

Task T285316 shows that the issues is still happening, and is also reproducible via the API.

Task T285316 shows that the issues is still happening, and is also reproducible via the API.

I encountered [13508980-a6e3-40bf-b598-6c564e9786f4] Caught exception of type MWException when trying to move https://en.wikipedia.org/wiki/File:Candyman_(2020_film).png using the API. Same thing?

Same thing?

Not the same thing; see https://meta.wikimedia.org/wiki/Tech/News/2021/26 section "Problems" EDIT: Sorry, I'm wrong. I should have looked closer into Logstash.
This one is:

Failed to create null revision while moving page ID 63213261 to File:Candyman_(2021_film).png (page ID 63213261)

from /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(974)
#0 /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(659): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(471): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMove.php(213): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMove.php(110): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMain.php(1721): ApiMove->execute()
#5 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMain.php(702): ApiMain->executeAction()

Same thing?

Not the same thing; see https://meta.wikimedia.org/wiki/Tech/News/2021/26 section "Problems" EDIT: Sorry, I'm wrong. I should have looked closer into Logstash.
This one is:

Failed to create null revision while moving page ID 63213261 to File:Candyman_(2021_film).png (page ID 63213261)

from /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(974)
#0 /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(659): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.37.0-wmf.11/includes/MovePage.php(471): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMove.php(213): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMove.php(110): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMain.php(1721): ApiMove->execute()
#5 /srv/mediawiki/php-1.37.0-wmf.11/includes/api/ApiMain.php(702): ApiMain->executeAction()

Thanks. I tried to move https://en.wikipedia.org/wiki/File:Geroge_Washington_Monument_(Richard_Henry_Park_statue,_Milwaukee).jpg but got:

[89697627-5487-4472-9f30-e4beb3463fed] Caught exception of type MWException

The code was internal_api_error_MWException. And again it worked the second time. As these errors are intermittent I never get a chance to look at the full API response to see if any more detailed error message is available.

Also confirmed on betacommons when I tried to move https://commons.wikimedia.beta.wmflabs.org/wiki/File:76f2dbef4cc9_26_38.jpg:

[YN-EiHVn7C6n6OXJASTqzgAAABE] Exception caught: Failed to create null revision while moving page ID 100001 to File:76f2dbef4cc9_26_39.jpg (page ID 100001)
Got the API response this time.

{"error":{"code":"internal_api_error_MWException","info":"[YN-EiHVn7C6n6OXJASTqzgAAABE] Exception caught: Failed to create null revision while moving page ID 100001 to File:76f2dbef4cc9_26_39.jpg (page ID 100001)","errorclass":"MWException","*":"MWException at /srv/mediawiki/php-master/includes/MovePage.php(974)
from /srv/mediawiki/php-master/includes/MovePage.php(974)
#0 /srv/mediawiki/php-master/includes/MovePage.php(659): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-master/includes/MovePage.php(471): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-master/includes/api/ApiMove.php(216): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-master/includes/api/ApiMove.php(113): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-master/includes/api/ApiMain.php(1811): ApiMove->execute()
#5 /srv/mediawiki/php-master/includes/api/ApiMain.php(790): ApiMain->executeAction()
#6 /srv/mediawiki/php-master/includes/api/ApiMain.php(761): ApiMain->executeActionWithErrorHandling()
#7 /srv/mediawiki/php-master/api.php(90): ApiMain->execute()
#8 /srv/mediawiki/php-master/api.php(45): wfApiMain()
#9 /srv/mediawiki/w/api.php(3): require(string)
#10 {main}"},"servedby":"deployment-mediawiki11"}

https://commons.wikimedia.beta.wmflabs.org/wiki/File:76f2dbef4cc9_26_39.jpg
[YOErxFvNVWOiDf6sPUgDyAAAABI] Exception caught: Failed to create null revision while moving page ID 100001 to File:76f2dbef4cc9_26_40.jpg (page ID 100001) (code: internal_api_error_MWException)

https://commons.wikimedia.beta.wmflabs.org/wiki/File:76f2dbef4cc9_26_40.jpg
[YOEsZ1vNVWOiDf6sPUgEsgAAABg] Exception caught: Failed to create null revision while moving page ID 100001 to File:76f2dbef4cc9_26_41.jpg (page ID 100001) (code: internal_api_error_MWException)

https://commons.wikimedia.beta.wmflabs.org/wiki/File:76f2dbef4cc9_26_41.jpg
[YOEssFvNVWOiDf6sPUgFNwAAABQ] Exception caught: Failed to create null revision while moving page ID 100001 to File:76f2dbef4cc9_26_42.jpg (page ID 100001) (code: internal_api_error_MWException)

I guess it's reproducible now. My userscript edits the page shortly before moving it, maybe that's a factor?

Change 609570 merged by jenkins-bot:
[mediawiki/core@master] Add extra details to error log to debug why null revision creation is failing

https://gerrit.wikimedia.org/r/609570

@daniel This patch added error instrumentation from RevisionStore which was meant to provide more information to figure out what's causing this. The instrumention is still there today (source), but appears to not get hit (there are no hits for it in the past 30 days).

...and we are still seeing this error, even though the code path with the extra info is not hit at all. Curious.

Change 609570 merged by jenkins-bot:
[mediawiki/core@master] Add extra details to error log to debug why null revision creation is failing

https://gerrit.wikimedia.org/r/609570

@daniel This patch added error instrumentation from RevisionStore which was meant to provide more information to figure out what's causing this. The instrumention is still there today (source), but appears to not get hit (there are no hits for it in the past 30 days).

...and we are still seeing this error, even though the code path with the extra info is not hit at all. Curious.

I've added reproduction steps so you don't have to wait for someone to encounter this error.

I've adjusted LuckyRename again, you can now move any file and it'll trigger internal_api_error_MWException.

[YPGtmdwyviV4yN6a-P59fQAAAJU] Exception caught: Failed to create null revision while moving page ID 100000 to File:76f2dbef4cc9_24_3.jpg (page ID 100000)

MWException at /srv/mediawiki/php-master/includes/MovePage.php(974)
from /srv/mediawiki/php-master/includes/MovePage.php(974)
#0 /srv/mediawiki/php-master/includes/MovePage.php(659): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-master/includes/MovePage.php(471): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-master/includes/api/ApiMove.php(223): MovePage->move(User, string, boolean, array)
#3 /srv/mediawiki/php-master/includes/api/ApiMove.php(120): ApiMove->movePage(Title, Title, string, boolean, array)
#4 /srv/mediawiki/php-master/includes/api/ApiMain.php(1842): ApiMove->execute()
#5 /srv/mediawiki/php-master/includes/api/ApiMain.php(821): ApiMain->executeAction()
#6 /srv/mediawiki/php-master/includes/api/ApiMain.php(792): ApiMain->executeActionWithErrorHandling()
#7 /srv/mediawiki/php-master/api.php(90): ApiMain->execute()
#8 /srv/mediawiki/php-master/api.php(45): wfApiMain()
#9 /srv/mediawiki/w/api.php(3): require(string)
#10 {main}

It's probably a database locking issue, it may be resolved by doing exactly what LuckyRename does: wait for the dust to settle and try again.

FTR, this seems to be still happening. Current backtrace:

[e3b317d0-425c-4fc6-bfcc-0d987f05f65b] /w/index.php?title=Speciale:Sposta&action=submit   MWException: Failed to create null revision while moving page ID 9231371 to Amaury_Cordeel (page ID 9231371)
from /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(953)
#0 /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(686): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(532): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.38.0-wmf.18/includes/specials/SpecialMovepage.php(724): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.38.0-wmf.18/includes/specials/SpecialMovepage.php(207): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.38.0-wmf.18/includes/specialpage/SpecialPage.php(671): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.38.0-wmf.18/includes/specialpage/SpecialPageFactory.php(1378): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(314): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext)
#7 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(903): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(563): MediaWiki->main()
#9 /srv/mediawiki/php-1.38.0-wmf.18/index.php(53): MediaWiki->run()
#10 /srv/mediawiki/php-1.38.0-wmf.18/index.php(46): wfIndexMain()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}

FTR, this seems to be still happening. Current backtrace:

[e3b317d0-425c-4fc6-bfcc-0d987f05f65b] /w/index.php?title=Speciale:Sposta&action=submit   MWException: Failed to create null revision while moving page ID 9231371 to Amaury_Cordeel (page ID 9231371)
from /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(953)
#0 /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(686): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.38.0-wmf.18/includes/MovePage.php(532): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.38.0-wmf.18/includes/specials/SpecialMovepage.php(724): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.38.0-wmf.18/includes/specials/SpecialMovepage.php(207): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.38.0-wmf.18/includes/specialpage/SpecialPage.php(671): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.38.0-wmf.18/includes/specialpage/SpecialPageFactory.php(1378): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(314): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext)
#7 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(903): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.38.0-wmf.18/includes/MediaWiki.php(563): MediaWiki->main()
#9 /srv/mediawiki/php-1.38.0-wmf.18/index.php(53): MediaWiki->run()
#10 /srv/mediawiki/php-1.38.0-wmf.18/index.php(46): wfIndexMain()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}

What were you doing, on what wiki?

What were you doing, on what wiki?

This is from another user who experienced this issue on itwiki. My understanding is that the error is shown as soon as they try to move a page using a gadget (should be this one).

Seems like this bug can affect all action=move API requests. Also, another thing I forgot to mention, is that it seems to be happening constantly, roughly 10-15 times a day.

What were you doing, on what wiki?

This is from another user who experienced this issue on itwiki. My understanding is that the error is shown as soon as they try to move a page using a gadget (should be this one).

Seems like this bug can affect all action=move API requests. Also, another thing I forgot to mention, is that it seems to be happening constantly, roughly 10-15 times a day.

Got a diff, or diff for a similar action with that gadget? I suspect the gadget edits the page and immediately after tries to move it. Solving it would require changing the code to act like this:

MenuDialog.prototype.moveDraft = function ( newTitle, editSummary ) {
	// Sposta bozza
	return new mw.Api().postWithToken( 'csrf', {
		action: 'move',
		from: conf.wgPageName,
		to: newTitle,
		reason: editSummary,
		movetalk: 1,
		noredirect: 1,
		watchlist: 'nochange',
		format: 'json'
	} ).done( function ( data ) {
		return new mw.Api().postWithToken( 'csrf', {
			action: 'edit',
			format: 'json',
			title: newTitle,
			text: wikitext,
			summary: 'Esito revisione bozza',
			nocreate: 1,
			watchlist: 'nochange',
			starttimestamp: revision.timestamp,
			baserevid: conf.wgRevisionId
		} );
	} );
};

Or something like that, I didn't examine too closely what it's supposed to do exactly. @Sakretsu This would cause the page to be moved first and edited second.

Got a diff, or diff for a similar action with that gadget? I suspect the gadget edits the page and immediately after tries to move it.

No, it moves the page and that's it. See the history of Amaury Cordeel, the article was edited manually before the move.

Got a diff, or diff for a similar action with that gadget? I suspect the gadget edits the page and immediately after tries to move it.

No, it moves the page and that's it. See the history of Amaury Cordeel, the article was edited manually before the move.

Are you saying it's impossible for "Pubblica esito" (or any other API call that does anything to the page) to run before the move? Did you just edit the page and initiate the move after the edit really really quickly?

Are you saying it's impossible for "Pubblica esito" (or any other API call that does anything to the page) to run before the move? Did you just edit the page and initiate the move after the edit really really quickly?

Exactly, there's no API call that affects the page before the move. The API call that you mention occurs when the draft submission is declined. In that case the gadget edits the page instead of moving it to the main namespace.

Anyway I just read the discussion about this error on it.wiki and as I understand it the user who moved Amaury Cordeel did not use the gadget at all. The error message showed up after clicking the "Move page" button on Special:MovePage.

Are you saying it's impossible for "Pubblica esito" (or any other API call that does anything to the page) to run before the move? Did you just edit the page and initiate the move after the edit really really quickly?

Exactly, there's no API call that affects the page before the move. The API call that you mention occurs when the draft submission is declined. In that case the gadget edits the page instead of moving it to the main namespace.

Anyway I just read the discussion about this error on it.wiki and as I understand it the user who moved Amaury Cordeel did not use the gadget at all. The error message showed up after clicking the "Move page" button on Special:MovePage.

Did the user click the "Move page" button on Special:MovePage very very shortly after editing the page?

Anyway I just read the discussion about this error on it.wiki and as I understand it the user who moved Amaury Cordeel did not use the gadget at all. The error message showed up after clicking the "Move page" button on Special:MovePage.

Indeed, I evidently got confused; sorry about that.

Did the user click the "Move page" button on Special:MovePage very very shortly after editing the page?

According to the edit history, that could be possible: the page move was recorded 37 seconds after an edit to the same page.

Anyway I just read the discussion about this error on it.wiki and as I understand it the user who moved Amaury Cordeel did not use the gadget at all. The error message showed up after clicking the "Move page" button on Special:MovePage.

Indeed, I evidently got confused; sorry about that.

Did the user click the "Move page" button on Special:MovePage very very shortly after editing the page?

According to the edit history, that could be possible: the page move was recorded 37 seconds after an edit to the same page.

It's odd, according to https://it.wikipedia.org/w/index.php?title=Wikipedia:Officina&oldid=125243166#Errore_spostamento_da_ns118_a_ns0 they got

[e3b317d0-425c-4fc6-bfcc-0d987f05f65b] 2022-01-23 06:45:31: Errore irreversibile di tipo "MWException"

but the move succeeded anyway. (is that even possible? can an action succeed despite MWException?) 37 seconds should be enough for the edit to have been processed and not hinder the move. (if it were less than 10 it might not always be)

Got the same error at beta (moving a page with subpages):

[YfusvdH1iJ8JOhmMC2cS9wAAABA] /w/index.php?title=Speci%C3%A1ln%C3%AD:P%C5%99esunout_str%C3%A1nku&action=submit MWException: Failed to create null revision while moving page ID 1705 to Wikipedie:Potřebuji_pomoc/Mentoři/backup (page ID 1705)

Backtrace:

from /srv/mediawiki/php-master/includes/MovePage.php(953)
#0 /srv/mediawiki/php-master/includes/MovePage.php(686): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-master/includes/MovePage.php(532): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(724): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(207): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-master/includes/specialpage/SpecialPage.php(671): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-master/includes/specialpage/SpecialPageFactory.php(1378): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-master/includes/MediaWiki.php(314): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext)
#7 /srv/mediawiki/php-master/includes/MediaWiki.php(903): MediaWiki->performRequest()
#8 /srv/mediawiki/php-master/includes/MediaWiki.php(563): MediaWiki->main()
#9 /srv/mediawiki/php-master/index.php(53): MediaWiki->run()
#10 /srv/mediawiki/php-master/index.php(46): wfIndexMain()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}

Both moves succeeded (I was moving Wikipedie:Potřebuji pomoc/Mentoři to Wikipedie:Potřebuji pomoc/Mentoři/backup, including subpages).

I just realized that RevisionStore::newNullRevision logs an error whenever it's unable to create a null revision. For the beta error, this is what's logged (for itwp it's the same, just different IDs of course):

Failed to load latest revision ID 3613 of page ID 1705.
from /srv/mediawiki/php-master/includes/Revision/RevisionStore.php(1081)
#0 /srv/mediawiki/php-master/includes/MovePage.php(946): MediaWiki\Revision\RevisionStore->newNullRevision(Wikimedia\Rdbms\DBConnRef, Title, CommentStoreComment, boolean, User)
#1 /srv/mediawiki/php-master/includes/MovePage.php(686): MovePage->moveToInternal(User, Title, string, boolean, array)
#2 /srv/mediawiki/php-master/includes/MovePage.php(532): MovePage->moveUnsafe(User, string, boolean, array)
#3 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(724): MovePage->moveIfAllowed(User, string, boolean)
#4 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(207): MovePageForm->doSubmit()
#5 /srv/mediawiki/php-master/includes/specialpage/SpecialPage.php(671): MovePageForm->execute(NULL)
#6 /srv/mediawiki/php-master/includes/specialpage/SpecialPageFactory.php(1378): SpecialPage->run(NULL)
#7 /srv/mediawiki/php-master/includes/MediaWiki.php(314): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext)
#8 /srv/mediawiki/php-master/includes/MediaWiki.php(903): MediaWiki->performRequest()
#9 /srv/mediawiki/php-master/includes/MediaWiki.php(563): MediaWiki->main()
#10 /srv/mediawiki/php-master/index.php(53): MediaWiki->run()
#11 /srv/mediawiki/php-master/index.php(46): wfIndexMain()
#12 /srv/mediawiki/w/index.php(3): require(string)
#13 {main}

The first question that comes to mind is whether this could have to do with lock contention. I think I remember a similar issue (although perhaps it was with page deletion, not page move), and some comments in ::newNullRevision suggest that there've been lock-related issues in the past.

However, I'm even more puzzled by the page move succeeding anyway. MovePage throws an exception, so it should really halt the program and prevent any master change, which is clearly incompatible with the page move being 100% successful. As such, my second question, which is perhaps a bit silly, is: are we sure that the code is not attempting to move the page twice? If two requests were sent, it's possible that the first one succeeds, but the second one fails because the page has already been moved and there's no latest revision to load. Also, since the loading happens on the master DB, replication lag isn't a factor and this effect could in theory be observed with two almost-simultaneous requests.

Guess what, I clicked twice on the submit button very quickly, and what I got (on beta) is:

[Yf08E6Y6sww7aRkD5CKrkgAAAIs] /w/index.php?title=Special:MovePage&action=submit MWException: Failed to create null revision while moving page ID 271213 to User:Daimona_Eaytoy/Test2 (page ID 271213)

Backtrace:

from /srv/mediawiki/php-master/includes/MovePage.php(953)
#0 /srv/mediawiki/php-master/includes/MovePage.php(686): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-master/includes/MovePage.php(532): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(724): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-master/includes/specials/SpecialMovepage.php(207): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-master/includes/specialpage/SpecialPage.php(671): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-master/includes/specialpage/SpecialPageFactory.php(1378): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-master/includes/MediaWiki.php(314): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext)
#7 /srv/mediawiki/php-master/includes/MediaWiki.php(903): MediaWiki->performRequest()
#8 /srv/mediawiki/php-master/includes/MediaWiki.php(563): MediaWiki->main()
#9 /srv/mediawiki/php-master/index.php(53): MediaWiki->run()
#10 /srv/mediawiki/php-master/index.php(46): wfIndexMain()
#11 /srv/mediawiki/w/index.php(3): require(string)
#12 {main}

but the page move succeeded.

So I'd say the symptoms are compatible with the form being submitted twice. I believe two things should happen here:

  1. Understand why the form is being submitted twice: perhaps all past instances are from people who also double-clicked the submit button, or maybe it's an actual bug;
  2. Show a nice error to the user when this happens, since even with all kind of fixes in place, nothing prevents people from clicking the button twice.

Guess what, I clicked twice on the submit button very quickly, and what I got (on beta) is:

Ohhh! Nice :)

To prevent this, the form should contain the current revision ID in a hidden field. If that revision is no longer current when attempting to move the page, the attempt should fail with a meaningful error message. This is how edit conflict detection works, and we should apply the same logic here.

Guess what, I clicked twice on the submit button very quickly, and what I got (on beta) is:

Ohhh! Nice :)

To prevent this, the form should contain the current revision ID in a hidden field. If that revision is no longer current when attempting to move the page, the attempt should fail with a meaningful error message. This is how edit conflict detection works, and we should apply the same logic here.

You're overthinking this I think. This particular problem only exists in human users, bots don't double-click. So there is a way easier and better solution which I've integrated into all my userscripts for some time now: disable the button when it's pressed. I never realized MediaWiki never caught up to this.

The issue of bots/scripts that edit the page and try moving it directly afterwards is separate from this. If any script allows this error to be triggered by users who double-click it's the script that should be adjusted.

Guess what, I clicked twice on the submit button very quickly, and what I got (on beta) is:

Ohhh! Nice :)

To prevent this, the form should contain the current revision ID in a hidden field. If that revision is no longer current when attempting to move the page, the attempt should fail with a meaningful error message. This is how edit conflict detection works, and we should apply the same logic here.

You're overthinking this I think. This particular problem only exists in human users, bots don't double-click. So there is a way easier and better solution which I've integrated into all my userscripts for some time now: disable the button when it's pressed. I never realized MediaWiki never caught up to this.

The issue of bots/scripts that edit the page and try moving it directly afterwards is separate from this. If any script allows this error to be triggered by users who double-click it's the script that should be adjusted.

It is still possible that two human moves the page in the same time, maybe when it is asked on a sysop page etc.
But conflict detection on move is an old bug: T32211 - maybe this is just a duplicate of that

When it is a move conflict, that could mean the tasks T227869 is the same issue, where also a success and a error is reported for the move.

Guess what, I clicked twice on the submit button very quickly, and what I got (on beta) is:

Ohhh! Nice :)

To prevent this, the form should contain the current revision ID in a hidden field. If that revision is no longer current when attempting to move the page, the attempt should fail with a meaningful error message. This is how edit conflict detection works, and we should apply the same logic here.

You're overthinking this I think. This particular problem only exists in human users, bots don't double-click. So there is a way easier and better solution which I've integrated into all my userscripts for some time now: disable the button when it's pressed. I never realized MediaWiki never caught up to this.

The issue of bots/scripts that edit the page and try moving it directly afterwards is separate from this. If any script allows this error to be triggered by users who double-click it's the script that should be adjusted.

It is still possible that two human moves the page in the same time, maybe when it is asked on a sysop page etc.

In theory yes. In practice, when I try to move a page that was already moved with a redirect left:

The destination page "User:AJ/Sandbox9" already exists. Do you want to delete it to make way for the move?

And if I had suppressed it:

No such target page
The target page you have specified does not exist. Return to Main Page.

Also I can't seem to reproduce this by double-clicking like Daimona did. It must require some very narrow timing? In practice, disabling the button after pressing it is very simple, has no downside, will likely prevent most or all "null revision" errors from Special:MovePage, prevents the user from having to deal with any error message at all and it should be done anyway as double-clicking it can lead to unexpected results at any time.

Also I can't seem to reproduce this by double-clicking like Daimona did. It must require some very narrow timing?

Possibly. Also, I tried that on beta, and the usual beta lag might've helped.

Looks that this causes the following traceback. 15:22, 11 July 2019 Michal Bělka talk contribs block moved page František Lydie Gahura to František Lýdie Gahura (s přesměrováním, používají se zjevně obě varianty) (revert) (thank) happened on cs.wp while User:Janbery was moving the same page in the same minute, with the following error.

[XSc4DgpAICsAADlL5JwAAABT] /w/index.php?title=Speci%C3%A1ln%C3%AD:P%C5%99esunout_str%C3%A1nku&action=submit   MWException from line 763 of /srv/mediawiki/php-1.34.0-wmf.11/includes/MovePage.php: Failed to create null revision while moving page ID 262828 to František_Lýdie_Gahura
#0 /srv/mediawiki/php-1.34.0-wmf.11/includes/MovePage.php(452): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.34.0-wmf.11/includes/MovePage.php(294): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.34.0-wmf.11/includes/specials/SpecialMovepage.php(610): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.34.0-wmf.11/includes/specials/SpecialMovepage.php(130): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.34.0-wmf.11/includes/specialpage/SpecialPage.php(571): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.34.0-wmf.11/includes/specialpage/SpecialPageFactory.php(581): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.34.0-wmf.11/includes/MediaWiki.php(288): MediaWiki\Special\SpecialPageFactory->executePath(Title, RequestContext)
#7 /srv/mediawiki/php-1.34.0-wmf.11/includes/MediaWiki.php(884): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.34.0-wmf.11/includes/MediaWiki.php(515): MediaWiki->main()
#9 /srv/mediawiki/php-1.34.0-wmf.11/index.php(42): MediaWiki->run()
#10 /srv/mediawiki/w/index.php(3): include(string)
#11 {main}

Still seen in prod, including from API requests.

Logstash: Single document

[{reqId}] {exception_url}   MWException: Failed to create null revision while moving page ID ### to ### (page ID ###)

from /srv/mediawiki/php-1.39.0-wmf.8/includes/MovePage.php(961)
#0 /srv/mediawiki/php-1.39.0-wmf.8/includes/MovePage.php(693): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.39.0-wmf.8/includes/MovePage.php(539): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.39.0-wmf.8/includes/api/ApiMove.php(120): MovePage->moveIfAllowed(User, string, boolean, array)
#3 /srv/mediawiki/php-1.39.0-wmf.8/includes/api/ApiMain.php(1902): ApiMove->execute()
#4 /srv/mediawiki/php-1.39.0-wmf.8/includes/api/ApiMain.php(874): ApiMain->executeAction()
#5 /srv/mediawiki/php-1.39.0-wmf.8/includes/api/ApiMain.php(845): ApiMain->executeActionWithErrorHandling()
#6 /srv/mediawiki/php-1.39.0-wmf.8/api.php(90): ApiMain->execute()
#7 /srv/mediawiki/php-1.39.0-wmf.8/api.php(45): wfApiMain()
#8 /srv/mediawiki/w/api.php(3): require(string)
#9 {main}