{"record":{"id":"f75043f04670a5a0","repo":"w7corp/easywechat","slug":"failed-to-get-component-access-token-s","errorCode":null,"errorMessage":"Failed to get component_access_token: %s","messagePattern":"Failed to get component_access_token: (.+?)","errorType":"exception","errorClass":"HttpException","httpStatus":null,"severity":"critical","filePath":"src/OpenPlatform/ComponentAccessToken.php","lineNumber":86,"sourceCode":"    /**\n     * @throws HttpException\n     */\n    public function refresh(): string\n    {\n        $response = $this->httpClient->request(\n            'POST',\n            'cgi-bin/component/api_component_token',\n            [\n                'json' => [\n                    'component_appid' => $this->appId,\n                    'component_appsecret' => $this->secret,\n                    'component_verify_ticket' => $this->verifyTicket->getTicket(),\n                ],\n            ]\n        )->toArray(false);\n\n        if (empty($response['component_access_token'])) {\n            throw new HttpException('Failed to get component_access_token: '.json_encode(\n                $response,\n                JSON_UNESCAPED_UNICODE\n            ));\n        }\n\n        $this->cache->set(\n            $this->getKey(),\n            $response['component_access_token'],\n            abs(intval($response['expires_in']) - 100)\n        );\n\n        return $response['component_access_token'];\n    }\n}\n","sourceCodeStart":68,"sourceCodeEnd":101,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/OpenPlatform/ComponentAccessToken.php#L68-L101","documentation":"ComponentAccessToken fetches the component_access_token by POSTing component appid, secret and the current component_verify_ticket to cgi-bin/component/api_component_token, then caches it (expires_in minus 100 seconds). HttpException with the embedded JSON is thrown when WeChat returns no component_access_token — one of the three ingredients was rejected. Every open-platform API call depends on this token, so the whole component goes down when it fails.","triggerScenarios":"component_verify_ticket stale (cache holds an old push while WeChat rotated it); wrong component_appid/component_appsecret; the ticket cache wiped mid-flight so the ticket used is empty/old; the component app not approved or frozen.","commonSituations":"Secret rotated in the console but not in env; file/local caches not shared so consumers read an old ticket; deploys switching Redis or changing cache prefixes; new component apps before their first ticket push arrives.","solutions":["Decode the embedded errcode/errmsg — invalid-secret and invalid-ticket codes point to different fixes","Fix the component secret in config if it was rotated, then redeploy/clear config cache","Ensure verify-ticket pushes land on the shared cache so the freshest ticket is always used","Retry after the next ticket push if the cache was stale"],"exampleFix":"// before: per-instance file cache → consumers read a stale component_verify_ticket → 40001 cycle\n$openPlatform->setCache(new \\Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter());\n\n// after: shared Redis for both the push receiver and every worker\n$openPlatform->setCache(new \\Symfony\\Component\\Cache\\Adapter\\RedisAdapter($redis, 'easywechat'));","handlingStrategy":"try-catch","validationCode":"if (blank($config['component_appid'] ?? null) || blank($config['component_secret'] ?? null)) {\n    throw new \\RuntimeException('OpenPlatform component appid/secret must be set.');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $token = $componentAccessToken->getToken();\n} catch (\\EasyWeChat\\Kernel\\Exceptions\\HttpException $e) {\n    $payload = json_decode(strstr($e->getMessage(), '{') ?: '[]', true) ?: [];\n    $errcode = $payload['errcode'] ?? null;\n    // 40001 → stale verify ticket (check push receiver + shared cache); 40125-class → secret\n    report($e);\n}","preventionTips":["Share one Redis (same prefix) between the ticket receiver and all component-token consumers","Rotate the component secret in console and env in one change, then flush caches","Treat repeated 40001s on this endpoint as 'ticket pushes stopped arriving', not random failure"],"tags":["php","easywechat","wechat","open-platform","access-token","credentials","cache"],"backgroundTag":"access-token-request-failed","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}