Page MenuHomePhabricator

[{reqId}] {exception_url} Wikimedia\Rdbms\DBQueryError: Error 1062: Duplicate entry 'X-X-X' for key 'PRIMARY' Function: MediaWiki\CheckUser\Services\UserAgentClientHintsManager::insertMappingRows
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
message
[{reqId}] {exception_url}   Wikimedia\Rdbms\DBQueryError: Error 1062: Duplicate entry 'X-X-X' for key 'PRIMARY'
Function: MediaWiki\CheckUser\Services\UserAgentClientHintsManager::insertMappingRows
Query: INSERT INTO `cu_useragent_clienthints_
trace
from /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/Database.php(1236)
#0 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/Database.php(1220): Wikimedia\Rdbms\Database->getQueryException(string, integer, string, string)
#1 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/Database.php(1194): Wikimedia\Rdbms\Database->getQueryExceptionAndLog(string, integer, string, string)
#2 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/Database.php(679): Wikimedia\Rdbms\Database->reportQueryError(string, integer, string, string, boolean)
#3 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/Database.php(1509): Wikimedia\Rdbms\Database->query(Wikimedia\Rdbms\Query, string)
#4 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/DBConnRef.php(119): Wikimedia\Rdbms\Database->insert(string, array, string)
#5 /srv/mediawiki/php-1.41.0-wmf.22/includes/libs/rdbms/database/DBConnRef.php(402): Wikimedia\Rdbms\DBConnRef->__call(string, array)
#6 /srv/mediawiki/php-1.41.0-wmf.22/extensions/CheckUser/src/Services/UserAgentClientHintsManager.php(170): Wikimedia\Rdbms\DBConnRef->insert(string, array, string)
#7 /srv/mediawiki/php-1.41.0-wmf.22/extensions/CheckUser/src/Services/UserAgentClientHintsManager.php(105): MediaWiki\CheckUser\Services\UserAgentClientHintsManager->insertMappingRows(MediaWiki\CheckUser\ClientHints\ClientHintsData, integer, string, boolean)
#8 /srv/mediawiki/php-1.41.0-wmf.22/extensions/CheckUser/src/Api/Rest/Handler/UserAgentClientHintsHandler.php(94): MediaWiki\CheckUser\Services\UserAgentClientHintsManager->insertClientHintValues(MediaWiki\CheckUser\ClientHints\ClientHintsData, integer, string)
#9 /srv/mediawiki/php-1.41.0-wmf.22/includes/Rest/SimpleHandler.php(38): MediaWiki\CheckUser\Api\Rest\Handler\UserAgentClientHintsHandler->run(string, integer)
#10 /srv/mediawiki/php-1.41.0-wmf.22/includes/Rest/Router.php(517): MediaWiki\Rest\SimpleHandler->execute()
#11 /srv/mediawiki/php-1.41.0-wmf.22/includes/Rest/Router.php(422): MediaWiki\Rest\Router->executeHandler(MediaWiki\CheckUser\Api\Rest\Handler\UserAgentClientHintsHandler)
#12 /srv/mediawiki/php-1.41.0-wmf.22/includes/Rest/EntryPoint.php(195): MediaWiki\Rest\Router->execute(MediaWiki\Rest\RequestFromGlobals)
#13 /srv/mediawiki/php-1.41.0-wmf.22/includes/Rest/EntryPoint.php(135): MediaWiki\Rest\EntryPoint->execute()
#14 /srv/mediawiki/php-1.41.0-wmf.22/rest.php(31): MediaWiki\Rest\EntryPoint::main()
#15 /srv/mediawiki/w/rest.php(3): require(string)
#16 {main}
Impact

Stops storage of Client Hints data.

Notes

Based on an inspection of the query, it seems like the INSERT query attempts to insert the same row twice. This query is not an INSERT IGNORE query, but the attempt to insert the same row in the same query should be fixed instead of just specifying an ignore.

Related Objects

Event Timeline

Change 951822 had a related patch set uploaded (by Dreamy Jazz; author: Dreamy Jazz):

[mediawiki/extensions/CheckUser@master] clienthints: Remove duplicate entries when inserting to map table

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

Change 951822 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@master] clienthints: Remove duplicate entries when converting to DB rows

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

Change 951846 had a related patch set uploaded (by Dreamy Jazz; author: Dreamy Jazz):

[mediawiki/extensions/CheckUser@wmf/1.41.0-wmf.22] clienthints: Remove duplicate entries when converting to DB rows

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

Change 951847 had a related patch set uploaded (by Dreamy Jazz; author: Dreamy Jazz):

[mediawiki/extensions/CheckUser@wmf/1.41.0-wmf.23] clienthints: Remove duplicate entries when converting to DB rows

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

Change 951847 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@wmf/1.41.0-wmf.23] clienthints: Remove duplicate entries when converting to DB rows

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

Mentioned in SAL (#wikimedia-operations) [2023-08-23T13:17:42Z] <lucaswerkmeister-wmde@deploy1002> Started scap: Backport for [[gerrit:951847|clienthints: Remove duplicate entries when converting to DB rows (T344787)]]

Mentioned in SAL (#wikimedia-operations) [2023-08-23T13:19:17Z] <lucaswerkmeister-wmde@deploy1002> lucaswerkmeister-wmde and dreamyjazz: Backport for [[gerrit:951847|clienthints: Remove duplicate entries when converting to DB rows (T344787)]] synced to the testservers mwdebug1001.eqiad.wmnet, mwdebug2001.codfw.wmnet, mwdebug2002.codfw.wmnet, mwdebug1002.eqiad.wmnet, and mw-debug kubernetes deployment (accessible via k8s-experimental XWD option)

Mentioned in SAL (#wikimedia-operations) [2023-08-23T13:38:55Z] <lucaswerkmeister-wmde@deploy1002> Finished scap: Backport for [[gerrit:951847|clienthints: Remove duplicate entries when converting to DB rows (T344787)]] (duration: 21m 12s)

Change 951846 merged by jenkins-bot:

[mediawiki/extensions/CheckUser@wmf/1.41.0-wmf.22] clienthints: Remove duplicate entries when converting to DB rows

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

Mentioned in SAL (#wikimedia-operations) [2023-08-23T13:53:19Z] <lucaswerkmeister-wmde@deploy1002> Started scap: Backport for [[gerrit:951846|clienthints: Remove duplicate entries when converting to DB rows (T344787)]]

Mentioned in SAL (#wikimedia-operations) [2023-08-23T13:54:49Z] <lucaswerkmeister-wmde@deploy1002> dreamyjazz and lucaswerkmeister-wmde: Backport for [[gerrit:951846|clienthints: Remove duplicate entries when converting to DB rows (T344787)]] synced to the testservers mwdebug1002.eqiad.wmnet, mwdebug2002.codfw.wmnet, mwdebug1001.eqiad.wmnet, mwdebug2001.codfw.wmnet, and mw-debug kubernetes deployment (accessible via k8s-experimental XWD option)

Mentioned in SAL (#wikimedia-operations) [2023-08-23T14:06:30Z] <lucaswerkmeister-wmde@deploy1002> Finished scap: Backport for [[gerrit:951846|clienthints: Remove duplicate entries when converting to DB rows (T344787)]] (duration: 13m 10s)

@Dreamy_Jazz I think I can reproduce this, in a slightly different way, although I am not exactly sure how. The JSON payloads:

{"brands": {"-70": "n", "null": -19480, "false": "\\u00887\\u0007", "\\u0016\\ud95c\\udda46BX": true, "m": ""}, "fullVersionList": ["\\ud99f\\udfdb", "\\u00f8\\n\\ud8e2\\udf67\\u001e", null]}
{"brands": {"-70": "n"}, "fullVersionList": ["\\ud99f\\udfdb"]}
{'bitness': None, 'platformVersion': 29280, 'brands': {-70: 'n', None: -19480, False: '\x887\x07', '\x16\U000671a46BX': True, 'm': ''}, 'platform': '', 'architecture': None, 'fullVersionList': ['\U00077fdb', 'ø\n\U00048b67\x1e', None], 'mobile': 'r', 'model': False}

Returns

{
  "message": "Error: exception of type Wikimedia\\Rdbms\\DBQueryError: Error 1062: Duplicate entry '0-0-16881' for key 'PRIMARY'\nFunction: MediaWiki\\CheckUser\\Services\\UserAgentClientHintsManager::insertMappingRows\nQuery: INSERT INTO `cu_useragent_clienthints_map` (uachm_uach_id,uachm_reference_type,uachm_reference_id) VALUES (0,0,16881),(0,0,16881)\n",
  "exception": {
    "id": "2e8bb688564afc0877ef4559",
    "type": "Wikimedia\\Rdbms\\DBQueryError",
    "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/Database.php",
    "line": 1236,
    "message": "Error 1062: Duplicate entry '0-0-16881' for key 'PRIMARY'\nFunction: MediaWiki\\CheckUser\\Services\\UserAgentClientHintsManager::insertMappingRows\nQuery: INSERT INTO `cu_useragent_clienthints_map` (uachm_uach_id,uachm_reference_type,uachm_reference_id) VALUES (0,0,16881),(0,0,16881)\n",
    "code": 0,
    "url": "/bare/rest.php/checkuser/v0/useragent-clienthints/revision/16881",
    "caught_by": "other",
    "backtrace": [
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/Database.php",
        "line": 1220,
        "function": "getQueryException",
        "class": "Wikimedia\\Rdbms\\Database",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/Database.php",
        "line": 1194,
        "function": "getQueryExceptionAndLog",
        "class": "Wikimedia\\Rdbms\\Database",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/Database.php",
        "line": 679,
        "function": "reportQueryError",
        "class": "Wikimedia\\Rdbms\\Database",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/Database.php",
        "line": 1509,
        "function": "query",
        "class": "Wikimedia\\Rdbms\\Database",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/DBConnRef.php",
        "line": 119,
        "function": "insert",
        "class": "Wikimedia\\Rdbms\\Database",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/database/DBConnRef.php",
        "line": 402,
        "function": "__call",
        "class": "Wikimedia\\Rdbms\\DBConnRef",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/libs/rdbms/querybuilder/InsertQueryBuilder.php",
        "line": 213,
        "function": "insert",
        "class": "Wikimedia\\Rdbms\\DBConnRef",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/extensions/CheckUser/src/Services/UserAgentClientHintsManager.php",
        "line": 180,
        "function": "execute",
        "class": "Wikimedia\\Rdbms\\InsertQueryBuilder",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/extensions/CheckUser/src/Services/UserAgentClientHintsManager.php",
        "line": 114,
        "function": "insertMappingRows",
        "class": "MediaWiki\\CheckUser\\Services\\UserAgentClientHintsManager",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/extensions/CheckUser/src/Api/Rest/Handler/UserAgentClientHintsHandler.php",
        "line": 113,
        "function": "insertClientHintValues",
        "class": "MediaWiki\\CheckUser\\Services\\UserAgentClientHintsManager",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/Rest/SimpleHandler.php",
        "line": 38,
        "function": "run",
        "class": "MediaWiki\\CheckUser\\Api\\Rest\\Handler\\UserAgentClientHintsHandler",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/Rest/Router.php",
        "line": 517,
        "function": "execute",
        "class": "MediaWiki\\Rest\\SimpleHandler",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/Rest/Router.php",
        "line": 422,
        "function": "executeHandler",
        "class": "MediaWiki\\Rest\\Router",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/Rest/EntryPoint.php",
        "line": 195,
        "function": "execute",
        "class": "MediaWiki\\Rest\\Router",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/includes/Rest/EntryPoint.php",
        "line": 135,
        "function": "execute",
        "class": "MediaWiki\\Rest\\EntryPoint",
        "type": "->"
      },
      {
        "file": "/home/drw/wikimedia/srv/bare/rest.php",
        "line": 31,
        "function": "main",
        "class": "MediaWiki\\Rest\\EntryPoint",
        "type": "::"
      }
    ]
  },
  "httpCode": 500,
  "httpReason": "Internal Server Error"
}

Perhaps like T344979, we should only record the keys from brands and fullVersionList which we expect to get (brand and version) and ignore or reject anything else.

@Dreamy_Jazz I think I can reproduce this, in a slightly different way, although I am not exactly sure how. The JSON payloads:

{"brands": {"-70": "n", "null": -19480, "false": "\\u00887\\u0007", "\\u0016\\ud95c\\udda46BX": true, "m": ""}, "fullVersionList": ["\\ud99f\\udfdb", "\\u00f8\\n\\ud8e2\\udf67\\u001e", null]}
{"brands": {"-70": "n"}, "fullVersionList": ["\\ud99f\\udfdb"]}

I got the warning from T344993 as an exception. This is likely due to different PHP versions. My docker instance seems to be running PHP 8.1.20. PHP docs for the function say that Passing the separator after the array is no longer supported. beyond version 8.

{'bitness': None, 'platformVersion': 29280, 'brands': {-70: 'n', None: -19480, False: '\x887\x07', '\x16\U000671a46BX': True, 'm': ''}, 'platform': '', 'architecture': None, 'fullVersionList': ['\U00077fdb', 'ø\n\U00048b67\x1e', None], 'mobile': 'r', 'model': False}

Running this on the master branch gives me a 400 error to do with a JSON parsing error


What I can see from the error you've shown is that it tries to insert for a row ID 0. This shouldn't occur, so I will make a patch that will not insert a map row if it has an invalid client hints data row ID.

What I can see from the error you've shown is that it tries to insert for a row ID 0. This shouldn't occur, so I will make a patch that will not insert a map row if it has an invalid client hints data row ID.

Created as T345024.

I no longer see an exception when the client hints data contains duplicate items in the brands or fullVersionList lists.

For example:

{"brands": [{"brand": "foo", "version": "bar"},{"brand": "foo", "version": "bar"},{"brand": "foo", "version": "bar"},{"brand": "foo", "version": "bar"}]}

Test environment: Local docker and bare-metal CheckUser 2.5 (9ed2b65) 19:12, 29 August 2023.