Page MenuHomePhabricator

Fatal exception on Special:MovePage: "Failed to create null revision while moving page ID 123 to Draft:Foo"
Closed, ResolvedPublicPRODUCTION 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.

Details

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

#0 /srv/mediawiki/php-1.35.0-wmf.1/includes/MovePage.php(517): MovePage->moveToInternal(User, Title, string, boolean, array)
#1 /srv/mediawiki/php-1.35.0-wmf.1/includes/MovePage.php(360): MovePage->moveUnsafe(User, string, boolean, array)
#2 /srv/mediawiki/php-1.35.0-wmf.1/includes/specials/SpecialMovepage.php(619): MovePage->moveIfAllowed(User, string, boolean)
#3 /srv/mediawiki/php-1.35.0-wmf.1/includes/specials/SpecialMovepage.php(130): MovePageForm->doSubmit()
#4 /srv/mediawiki/php-1.35.0-wmf.1/includes/specialpage/SpecialPage.php(575): MovePageForm->execute(NULL)
#5 /srv/mediawiki/php-1.35.0-wmf.1/includes/specialpage/SpecialPageFactory.php(611): SpecialPage->run(NULL)
#6 /srv/mediawiki/php-1.35.0-wmf.1/includes/MediaWiki.php(298): MediaWiki\Special\SpecialPageFactory->executePath(Title, RequestContext)
#7 /srv/mediawiki/php-1.35.0-wmf.1/includes/MediaWiki.php(967): MediaWiki->performRequest()
#8 /srv/mediawiki/php-1.35.0-wmf.1/includes/MediaWiki.php(530): MediaWiki->main()
#9 /srv/mediawiki/php-1.35.0-wmf.1/index.php(44): MediaWiki->run()
#10 /srv/mediawiki/w/index.php(3): require(string)
#11 {main}

Event Timeline

Ammarpad created this task.Oct 16 2019, 5:18 AM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptOct 16 2019, 5:18 AM
Aklapper renamed this task from Fatal exception on Special:MovePage to Fatal exception on Special:MovePage: "Failed to create null revision while moving page ID 123 to Draft:Foo".Oct 17 2019, 4:12 PM
Aklapper changed the subtype of this task from "Task" to "Production Error".
Aklapper set Request URL to /w/index.php?title=Special:MovePage&action=submit.
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}
brennen moved this task from Backlog to Logs/Train on the User-brennen board.
hashar added a subscriber: hashar.Jun 30 2020, 2:30 PM

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}
mmodell added a subscriber: mmodell.Jul 1 2020, 7:21 PM

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}
Ammarpad added a comment.EditedJul 5 2020, 7:50 AM

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 claimed this task.Jul 5 2020, 7:51 AM
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

hashar awarded a token.Jul 6 2020, 7:30 AM
hashar removed a subscriber: hashar.Jul 8 2020, 8:02 AM
kaldari added a subscriber: kaldari.Aug 4 2020, 3:40 PM

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

Ammarpad closed this task as Resolved.Sep 4 2020, 11:09 AM

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.