Page MenuHomePhabricator

TypeError: MediaWiki\Extension\OATHAuth\Key\TOTPKey::__construct(): Argument #3 ($recoveryCodes) must be of type array, string given, called in /srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Key/TOTPKey.php on line 12
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
  • mwversion: 1.45.0-wmf.22
  • timestamp: 2025-10-09T20:57:49.080Z
  • phpversion: 8.1.33
  • reqId: 15fe86b3-3935-44ca-94fa-ef8e107a2e62
  • Find reqId in Logstash
normalized_message
[{reqId}] {exception_url}   TypeError: MediaWiki\Extension\OATHAuth\Key\TOTPKey::__construct(): Argument #3 ($recoveryCodes) must be of type array, string given, called in /srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Key/TOTPKey.php on line 12
FrameLocationCall
from/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Key/TOTPKey.php(129)
#0/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Key/TOTPKey.php(125)MediaWiki\Extension\OATHAuth\Key\TOTPKey->__construct(int, string, string, string, string)
#1/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Module/TOTP.php(64)MediaWiki\Extension\OATHAuth\Key\TOTPKey::newFromArray(array)
#2/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/OATHUserRepository.php(272)MediaWiki\Extension\OATHAuth\Module\TOTP->newKey(array)
#3/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/OATHUserRepository.php(63)MediaWiki\Extension\OATHAuth\OATHUserRepository->loadKeysFromDatabase(MediaWiki\Extension\OATHAuth\OATHUser)
#4/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Hook/HookHandler.php(233)MediaWiki\Extension\OATHAuth\OATHUserRepository->findByUser(MediaWiki\User\User)
#5/srv/mediawiki/php-1.45.0-wmf.22/extensions/OATHAuth/src/Hook/HookHandler.php(249)MediaWiki\Extension\OATHAuth\Hook\HookHandler->getDisabledGroups(MediaWiki\User\User, array)
#6/srv/mediawiki/php-1.45.0-wmf.22/includes/HookContainer/HookContainer.php(141)MediaWiki\Extension\OATHAuth\Hook\HookHandler->onUserEffectiveGroups(MediaWiki\User\User, array)
#7/srv/mediawiki/php-1.45.0-wmf.22/includes/HookContainer/HookRunner.php(4837)MediaWiki\HookContainer\HookContainer->run(string, array)
#8/srv/mediawiki/php-1.45.0-wmf.22/includes/user/UserGroupManager.php(329)MediaWiki\HookContainer\HookRunner->onUserEffectiveGroups(MediaWiki\User\User, array)
#9/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/PermissionManager.php(1562)MediaWiki\User\UserGroupManager->getUserEffectiveGroups(MediaWiki\User\User)
#10/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/PermissionManager.php(1513)MediaWiki\Permissions\PermissionManager->getUserPermissions(MediaWiki\User\User)
#11/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/PermissionManager.php(852)MediaWiki\Permissions\PermissionManager->userHasRight(MediaWiki\User\User, string)
#12/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/PermissionManager.php(793)MediaWiki\Permissions\PermissionManager->getApplicableBlock(string, MediaWiki\User\User, string, MediaWiki\Title\Title, MediaWiki\Request\WebRequest)
#13/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/PermissionManager.php(513)MediaWiki\Permissions\PermissionManager->checkUserBlock(string, MediaWiki\User\User, MediaWiki\Permissions\PermissionStatus, string, bool, MediaWiki\Title\Title)
#14/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/UserAuthority.php(348)MediaWiki\Permissions\PermissionManager->getPermissionStatus(string, MediaWiki\User\User, MediaWiki\Title\Title, string)
#15/srv/mediawiki/php-1.45.0-wmf.22/includes/Permissions/UserAuthority.php(223)MediaWiki\Permissions\UserAuthority->internalCan(string, string, MediaWiki\Title\Title, MediaWiki\Permissions\PermissionStatus, int)
#16/srv/mediawiki/php-1.45.0-wmf.22/includes/user/User.php(3333)MediaWiki\Permissions\UserAuthority->authorizeRead(string, MediaWiki\Title\Title, MediaWiki\Permissions\PermissionStatus)
#17/srv/mediawiki/php-1.45.0-wmf.22/includes/actions/ActionEntryPoint.php(400)MediaWiki\User\User->authorizeRead(string, MediaWiki\Title\Title, MediaWiki\Permissions\PermissionStatus)
#18/srv/mediawiki/php-1.45.0-wmf.22/includes/actions/ActionEntryPoint.php(143)MediaWiki\Actions\ActionEntryPoint->performRequest()
#19/srv/mediawiki/php-1.45.0-wmf.22/includes/MediaWikiEntryPoint.php(184)MediaWiki\Actions\ActionEntryPoint->execute()
#20/srv/mediawiki/php-1.45.0-wmf.22/index.php(44)MediaWiki\MediaWikiEntryPoint->run()
#21/srv/mediawiki/w/index.php(3)require(string)
#22{main}
Impact
Notes

Details

Request URL
https://vote.wikimedia.org/wiki/Main_Page

Event Timeline

Reedy triaged this task as High priority.Oct 9 2025, 9:00 PM

UpdateTOTPScratchTokensToArray was never run on (at least) votewiki. We deleted it in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/OATHAuth/+/1189123

So a slightly modified version is needed because of schema changes; yes I know there's a var_dump:

<?php
/**
 * Updates TOTP Recovery Codes to an array
 *
 * Usage: php updateTOTPScratchTokensToArray.php
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 * @ingroup Maintenance
 */

namespace MediaWiki\Extension\OATHAuth\Maintenance;

use MediaWiki\Json\FormatJson;
use MediaWiki\Maintenance\LoggedUpdateMaintenance;
use MediaWiki\MediaWikiServices;

if ( getenv( 'MW_INSTALL_PATH' ) ) {
	$IP = getenv( 'MW_INSTALL_PATH' );
} else {
	$IP = __DIR__ . '/../../..';
}
require_once "$IP/maintenance/Maintenance.php";

/**
 * Merged December 2020; part of REL1_36
 */
class UpdateTOTPScratchTokensToArray extends LoggedUpdateMaintenance {
	public function __construct() {
		parent::__construct();
		$this->addDescription( 'Script to update TOTP Recovery Codes to an array' );
		$this->requireExtension( 'OATHAuth' );
	}

	protected function doDBUpdates() {
		$dbw = MediaWikiServices::getInstance()
			->getDBLoadBalancerFactory()
			->getPrimaryDatabase( 'virtual-oathauth' );

		$res = $dbw->newSelectQueryBuilder()
			->select( [ 'oad_id', 'oad_data' ] )
			->from( 'oathauth_devices' )
			->where( [ 'oad_type' => 1 ] )
			->caller( __METHOD__ )
			->fetchResultSet();

		foreach ( $res as $row ) {
			$data = FormatJson::decode( $row->oad_data, true );
			$updated = false;
			if ( is_string( $data['scratch_tokens'] ) ) {
				$data['scratch_tokens'] = explode( ',', $data['scratch_tokens'] );
				$updated = true;
			}

			if ( !$updated ) {
				continue;
			}
var_dump( $data );
			$dbw->newUpdateQueryBuilder()
				->update( 'oathauth_devices' )
				->set( [ 'oad_data' => FormatJson::encode( $data ) ] )
				->where( [ 'oad_id' => $row->oad_id ] )
				->caller( __METHOD__ )
				->execute();
		}

		$this->output( "Done.\n" );
		return true;
	}

	/**
	 * @return string
	 */
	protected function getUpdateKey() {
		return __CLASS__;
	}
}

$maintClass = UpdateTOTPScratchTokensToArray::class;
require_once RUN_MAINTENANCE_IF_MAIN;

Oof, thanks for the quick action in recognizing the problem and getting this fixed on the affected wikis!

Reedy claimed this task.

Done on all private and fishbowl wikis incase they were missed...