{"data":{"id":"magento2-40874","source":"github-pr","sourceRef":"magento/magento2#40874","title":"Fix PHP 8.5 deprecation: Using null as the key parameter for array_key_exists()","pr":{"number":40874,"url":"https://github.com/magento/magento2/pull/40874","author":"dimadidr","mergedAt":"2026-07-17T09:36:18Z","mergeCommit":"a48be2f81f16a4fdb0395e00dca54ce9c7254f3f","headCommit":"0f74fbbef2f777ba8e61c8b211ded1aefb784db1","baseRef":"2.4-develop","diffSha256":"64aae7bc77bcf6b2845a744cf01cffc2c8f682d03bba92ef4e765d7464ce0d1a"},"issues":[{"number":40875,"url":"https://github.com/magento/magento2/issues/40875","title":"[Issue] Fix PHP 8.5 deprecation: Using null as the key parameter for array_key_exists()","labels":["Area: Account","Component: Login","Issue: Confirmed","Priority: P1","Progress: PR Created","Progress: done","Reported on 2.4.9","Reproduced on 2.4.x"],"kind":"pr-derived"}],"fixedIn":null,"containingTags":[],"reportedOn":"2.4.9","codeMatch":{"2.4.6":"clean","2.4.6-p1":"clean","2.4.6-p2":"clean","2.4.6-p3":"clean","2.4.6-p4":"clean","2.4.6-p5":"clean","2.4.6-p6":"clean","2.4.6-p7":"clean","2.4.6-p8":"clean","2.4.6-p9":"clean","2.4.6-p10":"clean","2.4.6-p11":"clean","2.4.6-p12":"clean","2.4.6-p13":"clean","2.4.6-p14":"clean","2.4.6-p15":"clean","2.4.7":"clean","2.4.7-p1":"clean","2.4.7-p2":"clean","2.4.7-p3":"clean","2.4.7-p4":"clean","2.4.7-p5":"clean","2.4.7-p6":"clean","2.4.7-p7":"clean","2.4.7-p8":"clean","2.4.7-p9":"clean","2.4.7-p10":"clean","2.4.8":"clean","2.4.8-p1":"clean","2.4.8-p2":"clean","2.4.8-p3":"clean","2.4.8-p4":"clean","2.4.8-p5":"clean","2.4.9":"clean"},"affectedVersions":["2.4.6","2.4.6-p1","2.4.6-p2","2.4.6-p3","2.4.6-p4","2.4.6-p5","2.4.6-p6","2.4.6-p7","2.4.6-p8","2.4.6-p9","2.4.6-p10","2.4.6-p11","2.4.6-p12","2.4.6-p13","2.4.6-p14","2.4.6-p15","2.4.7","2.4.7-p1","2.4.7-p2","2.4.7-p3","2.4.7-p4","2.4.7-p5","2.4.7-p6","2.4.7-p7","2.4.7-p8","2.4.7-p9","2.4.7-p10","2.4.8","2.4.8-p1","2.4.8-p2","2.4.8-p3","2.4.8-p4","2.4.8-p5","2.4.9"],"components":["magento/module-captcha"],"files":[{"path":"app/code/Magento/Captcha/Helper/Data.php","change":"modified","package":"magento/module-captcha"},{"path":"app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php","change":"modified","package":"magento/module-captcha"}],"stripped":{"tests":["app/code/Magento/Captcha/Test/Unit/Helper/DataTest.php","app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php"],"docs":[],"outsideCode":[]},"linesChanged":17,"mergeBatched":false,"excluded":null,"sections":{"description":"On PHP 8.5, an AJAX customer login (e.g. the \"Checkout using your account\" sign-in popup) fails with **\"Could not authenticate. Please try again later\"** and the following deprecation is logged as `report.CRITICAL`:\n```\n[2026-06-11T19:13:56.998006+00:00] report.CRITICAL: Exception: Deprecated Functionality: Using null as the key parameter for array_key_exists() is deprecated, use an empty s\ntring instead in /var/www/vendor/magento/module-captcha/Helper/Data.php on line 92 in /var/www/vendor/magento/framework/App/ErrorHandler.php:61\nStack trace:\n#0 [internal function]: Magento\\Framework\\App\\ErrorHandler->handler(8192, 'Using null as t...', '/var/www/vendor...', 92)\n#1 /var/www/vendor/magento/module-captcha/Helper/Data.php(92): array_key_exists(NULL, Array)\n#2 /var/www/vendor/magento/module-captcha/Model/Customer/Plugin/AjaxLogin.php(94): Magento\\Captcha\\Helper\\Data->getCaptcha(NULL)\n#3 /var/www/vendor/magento/framework/Interception/Interceptor.php(135): Magento\\Captcha\\Model\\Customer\\Plugin\\AjaxLogin->aroundExecute(Object(Magento\\Customer\\Controller\\Aja\nx\\Login\\Interceptor), Object(Closure))\n#4 /var/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->{closure:Magento\\Framework\\Interception\\Intercept\nor::___callPlugins():104}()\n#5 /var/www/generated/code/Magento/Customer/Controller/Ajax/Login/Interceptor.php(23): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->___callPlugins('execute', Array, N\nULL)\n#6 /var/www/vendor/magento/framework/App/Action/Action.php(111): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->execute()\n#7 /var/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Framework\\App\\Action\\Action->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#8 /var/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->___callParent('dispatch', Array)\n#9 /var/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->{closure:Magento\\Framework\\Interception\\Intercept\nor::___callPlugins():104}(Object(Magento\\Framework\\App\\Request\\Http))\n#10 /var/www/generated/code/Magento/Customer/Controller/Ajax/Login/Interceptor.php(32): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->___callPlugins('dispatch', Array,\n Array)\n#11 /var/www/vendor/magento/framework/App/FrontController.php(245): Magento\\Customer\\Controller\\Ajax\\Login\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#12 /var/www/vendor/magento/framework/App/FrontController.php(212): Magento\\Framework\\App\\FrontController->getActionResponse(Object(Magento\\Customer\\Controller\\Ajax\\Login\\In\nterceptor), Object(Magento\\Framework\\App\\Request\\Http))\n#13 /var/www/vendor/magento/framework/App/FrontController.php(146): Magento\\Framework\\App\\FrontController->processRequest(Object(Magento\\Framework\\App\\Request\\Http), Object(\nMagento\\Customer\\Controller\\Ajax\\Login\\Interceptor))\n#14 /var/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Framework\\App\\FrontController->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#15 /var/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\Framework\\App\\FrontController\\Interceptor->___callParent('dispatch', Array)\n#16 /var/www/vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php(99): Magento\\Framework\\App\\FrontController\\Interceptor->{closure:Magento\\Framewor\nk\\Interception\\Interceptor::___callPlugins():104}(Object(Magento\\Framework\\App\\Request\\Http))\n#17 /var/www/vendor/magento/framework/Interception/Interceptor.php(135): Magento\\Store\\App\\FrontController\\Plugin\\RequestPreprocessor->aroundDispatch(Object(Magento\\Framewor\nk\\App\\FrontController\\Interceptor), Object(Closure), Object(Magento\\Framework\\App\\Request\\Http))\n#18 /var/www/vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php(72): Magento\\Framework\\App\\FrontController\\Interceptor->{closure:Magento\\Framework\\\nInterception\\Interceptor::___callPlugins():104}(Object(Magento\\Framework\\App\\Request\\Http))\n#19 /var/www/vendor/magento/framework/Interception/Interceptor.php(135): Magento\\PageCache\\Model\\App\\FrontController\\BuiltinPlugin->aroundDispatch(Object(Magento\\Framework\\A\npp\\FrontController\\Interceptor), Object(Closure), Object(Magento\\Framework\\App\\Request\\Http))\n#20 /var/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Framework\\App\\FrontController\\Interceptor->{closure:Magento\\Framework\\Interception\\Intercept\nor::___callPlugins():104}(Object(Magento\\Framework\\App\\Request\\Http))\n#21 /var/www/generated/code/Magento/Framework/App/FrontController/Interceptor.php(23): Magento\\Framework\\App\\FrontController\\Interceptor->___callPlugins('dispatch', Array, N\nULL)\n#22 /var/www/vendor/magento/framework/App/Http.php(116): Magento\\Framework\\App\\FrontController\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#23 /var/www/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Framework\\App\\Http->launch()\n#24 /var/www/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\Framework\\App\\Http\\Interceptor->___callParent('launch', Array)\n#25 /var/www/vendor/magento/module-application-performance-monitor/Plugin/ApplicationPerformanceMonitor.php(38): Magento\\Framework\\App\\Http\\Interceptor->{closure:Magento\\Fra\nmework\\Interception\\Interceptor::___callPlugins():104}()\n#26 /var/www/vendor/magento/framework/Interception/Interceptor.php(135): Magento\\ApplicationPerformanceMonitor\\Plugin\\ApplicationPerformanceMonitor->aroundLaunch(Object(Mage\nnto\\Framework\\App\\Http\\Interceptor), Object(Closure))\n#27 /var/www/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Framework\\App\\Http\\Interceptor->{closure:Magento\\Framework\\Interception\\Interceptor::___call\nPlugins():104}()\n#28 /var/www/generated/code/Magento/Framework/App/Http/Interceptor.php(23): Magento\\Framework\\App\\Http\\Interceptor->___callPlugins('launch', Array, NULL)\n#29 /var/www/vendor/magento/framework/App/Bootstrap.php(264): Magento\\Framework\\App\\Http\\Interceptor->launch()\n#30 /var/www/pub/index.php(30): Magento\\Framework\\App\\Bootstrap->run(Object(Magento\\Framework\\App\\Http\\Interceptor))\n#31 {main} {\"report_id\":\"2ae3a657eaf9a9217bb256096f1da0896e4ce0d7afe08a8200685c8aa1283a3d\",\"exception\":\"[object] (Exception(code: 0): Deprecated Functionality: Using null as\n the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/vendor/magento/module-captcha/Helper/Data.php on line 92 at /var/www/vendor/\nmagento/framework/App/ErrorHandler.php:61)\"} []\n\n```\n<img width=\"1920\" height=\"1080\" alt=\"image\" src=\"https://github.com/user-attachments/assets/500b817f-0a61-4f84-9d36-cf0f32b012c2\" />","stepsToReproduce":"1. Run Magento on PHP 8.5\n  2. Go to **Stores > Configuration > Sales > Checkout > Checkout Options** and set **Allow Guest Checkout** to **No**, then flush the cache\n  3. Make sure CAPTCHA for the `user_login` form is not forced (default config)\n  4. As a not-logged-in customer, add a product to the cart and proceed to checkout — the \"Checkout as a new customer / Checkout using your account\" popup appears\n  5. In the \"Checkout using your account\" block, enter the credentials of an existing customer and click **Sign In**\n  6. **Before the fix:** the request fails with \"Could not authenticate. Please try again later\", and `var/report`/`var/log` contains `report.CRITICAL: Exception: Deprecated\n  Functionality: Using null as the key parameter for array_key_exists() ... in module-captcha/Helper/Data.php on line 92`\n  7. **After the fix:** the customer signs in successfully and no deprecation is logged","expectedResult":null,"actualResult":null,"source":"pr"},"signatures":["[2026-06-11T19:13:56.998006+00:00] report.CRITICAL: Exception: Deprecated Functionality: Using null as the key parameter for array_key_exists() is deprecated, use an empty s","tring instead in","[internal function]: Magento\\Framework\\App\\ErrorHandler->handler(8192, 'Using null as t...', '', 92)","{main} {\"report_id\":\"\",\"exception\":\"[object] (Exception(code: 0): Deprecated Functionality: Using null as","magento/framework/App/ErrorHandler.php:61)\"} []","**Root cause:** when the AJAX login request payload does not contain `captcha_form_id`, `Magento\\Captcha\\Model\\Customer\\Plugin\\AjaxLogin::aroundExecute()` resolves the form id to `null` and passes it","6. **Before the fix:** the request fails with \"Could not authenticate. Please try again later\", and `var/report`/`var/log` contains `report.CRITICAL: Exception: Deprecated"],"labels":{"area":["Account"],"component":["Login"],"priority":"P1","severity":null,"reportedOn":["2.4.9"]},"categories":["Customer"],"triage":{"model":"@cf/cloudflare/clef","requestHash":"1c5a7590fbd43a76cca45777bce043c599abd308a8869ac93ac5e287fd1df9a1","isBugfix":0.9586,"changeKind":{"choice":"bugfix","probabilities":{"bugfix":0.9125,"feature":0.0116,"refactor":0.0316,"tests_only":0.012,"docs_only":0.0072,"dependency":0.0251},"confidence":0.8014},"scope":{"score":0.7738,"probabilities":{"0":0.3246,"1":0.577,"2":0.0984},"confidence":0.172},"risk":{"score":0.874,"probabilities":{"0":0.4902,"1":0.1455,"2":0.3643},"confidence":0.0913},"area":{"choice":"customer","probabilities":{"catalog":0.005,"checkout":0.0758,"customer":0.8626,"admin":0.0082,"graphql_api":0.0067,"framework":0.0151,"frontend":0.0091,"other":0.0175},"confidence":0.715},"securityRelevant":0.8013,"reportedVersion":{"choice":"2.4.9","probabilities":{"2.4.0":0.005,"2.4.0-p1":0.0043,"2.4.1":0.0038,"2.4.1-p1":0.0037,"2.4.2":0.0046,"2.4.2-p1":0.0044,"2.4.2-p2":0.0049,"2.4.3":0.0054,"2.4.3-p1":0.0062,"2.4.3-p2":0.0095,"2.4.3-p3":0.0051,"2.4.4":0.0059,"2.4.4-p1":0.0048,"2.4.4-p10":0.0054,"2.4.4-p11":0.0056,"2.4.4-p12":0.0055,"2.4.4-p13":0.0068,"2.4.4-p14":0.0066,"2.4.4-p15":0.005,"2.4.4-p16":0.0063,"2.4.4-p17":0.0049,"2.4.4-p18":0.0048,"2.4.4-p2":0.0031,"2.4.4-p3":0.0035,"2.4.4-p4":0.0039,"2.4.4-p5":0.0041,"2.4.4-p6":0.0048,"2.4.4-p7":0.0052,"2.4.4-p8":0.0062,"2.4.4-p9":0.0051,"2.4.5":0.0069,"2.4.5-p1":0.0049,"2.4.5-p10":0.0042,"2.4.5-p11":0.0091,"2.4.5-p12":0.0077,"2.4.5-p13":0.0063,"2.4.5-p14":0.0076,"2.4.5-p15":0.0067,"2.4.5-p16":0.0076,"2.4.5-p17":0.0058,"2.4.5-p2":0.0037,"2.4.5-p3":0.0044,"2.4.5-p4":0.0046,"2.4.5-p5":0.0048,"2.4.5-p6":0.0054,"2.4.5-p7":0.0054,"2.4.5-p8":0.0053,"2.4.5-p9":0.004,"2.4.6":0.0115,"2.4.6-p1":0.0067,"2.4.6-p10":0.0064,"2.4.6-p11":0.0086,"2.4.6-p12":0.0083,"2.4.6-p13":0.0097,"2.4.6-p14":0.0079,"2.4.6-p15":0.0077,"2.4.6-p2":0.0043,"2.4.6-p3":0.0048,"2.4.6-p4":0.0062,"2.4.6-p5":0.0073,"2.4.6-p6":0.0089,"2.4.6-p7":0.0086,"2.4.6-p8":0.0071,"2.4.6-p9":0.0051,"2.4.7":0.0116,"2.4.7-p1":0.008,"2.4.7-p10":0.0082,"2.4.7-p2":0.0051,"2.4.7-p3":0.009,"2.4.7-p4":0.0114,"2.4.7-p5":0.0115,"2.4.7-p6":0.0146,"2.4.7-p7":0.0109,"2.4.7-p8":0.0122,"2.4.7-p9":0.0053,"2.4.8":0.0224,"2.4.8-p1":0.0175,"2.4.8-p2":0.0123,"2.4.8-p3":0.0167,"2.4.8-p4":0.015,"2.4.8-p5":0.0144,"2.4.9":0.3076,"unspecified":0.1084},"confidence":0.1008},"backportWorthy":{"score":1.4267,"probabilities":{"0":0.1493,"1":0.2748,"2":0.5759},"confidence":0.1442}},"curated":{"title":"Fixes AJAX customer login failing on PHP 8.5 when captcha_form_id is missing","description":"On PHP 8.5, an AJAX customer login fails with 'Could not authenticate. Please try again later' when the request has no captcha_form_id, as null is passed as the key to array_key_exists() in Captcha Helper getCaptcha(). getCaptcha() now uses an empty string for a null form id, and in the AjaxLogin plugin a null form id now goes to return $proceed() before the captcha form validation.","categories":["Customer"],"author":"claude-code/opus-5.5","date":"2026-10-06","reviewedBy":null},"tests":{"2.4.8-p5":{"before":"fail","after":"pass","adapted":false,"runAt":"2026-10-06T09:20:33.389Z","releaseCommit":"870a22c63d9d9b68fa3297962e2d5d5841115814","suites":{"unit":{"before":"fail","after":"pass","runAt":"2026-10-06T09:20:33.389Z"}}},"2.4.9":{"before":"fail","after":"pass","adapted":false,"runAt":"2026-10-06T09:20:33.789Z","releaseCommit":"755e34dd689021c5165db9d35ecff74f7dc51527","suites":{"unit":{"before":"fail","after":"pass","runAt":"2026-10-06T09:20:33.789Z"}}},"2.4.7-p10":{"before":"fail","after":"pass","adapted":false,"runAt":"2026-10-06T09:29:35.641Z","releaseCommit":"72561bf80652f57cc642a03e2c9a51d74a285b14","suites":{"unit":{"before":"fail","after":"pass","runAt":"2026-10-06T09:29:35.641Z"}}}}},"_documentation":"https://magento.watch/api","_description":"Upstream fix magento2-40874 details"}