{"record":{"id":"3fa9955610bf77d0","repo":"w7corp/easywechat","slug":"failed-to-get-jssdk-agentticket-s-3fa995","errorCode":null,"errorMessage":"Failed to get jssdk agentTicket: %s","messagePattern":"Failed to get jssdk agentTicket: (.+?)","errorType":"exception","errorClass":"HttpException","httpStatus":null,"severity":"error","filePath":"src/Work/JsApiTicket.php","lineNumber":135,"sourceCode":"    }\n\n    /**\n     * @throws HttpException\n     */\n    public function getAgentTicket(int $agentId): string\n    {\n        $key = $this->getAgentKey($agentId);\n        $ticket = $this->cache->get($key);\n\n        if ($ticket && is_string($ticket)) {\n            return $ticket;\n        }\n\n        $response = $this->httpClient->request('GET', '/cgi-bin/ticket/get', ['query' => ['type' => 'agent_config']])\n            ->toArray(false);\n\n        if (empty($response['ticket'])) {\n            throw new HttpException('Failed to get jssdk agentTicket: '.json_encode($response, JSON_UNESCAPED_UNICODE));\n        }\n\n        $this->cache->set($key, $response['ticket'], intval($response['expires_in']));\n\n        return $response['ticket'];\n    }\n\n    public function getAgentKey(int $agentId): string\n    {\n        return sprintf('%s.%s', $this->getKey(), $agentId);\n    }\n}\n","sourceCodeStart":117,"sourceCodeEnd":148,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/Work/JsApiTicket.php#L117-L148","documentation":"Thrown by JsApiTicket::getAgentTicket() when GET /cgi-bin/ticket/get?type=agent_config returns no ticket. This ticket is specific to agent-level JS-SDK config (wx.agentConfig), and like the corp ticket, a missing ticket field normally reflects an invalid underlying access_token or a permission problem for that agent.","triggerScenarios":"Calling getAgentTicket($agentId) (or wx.agentConfig signature building) on cache miss. Produced by invalid/expired access_token, wrong agent secret for the agentId used, the agent lacking API permission, or the page domain not being the agent's trusted domain (errcode 40029/61005 in embedded body).","commonSituations":"Rendering wx.agentConfig in an in-app chat page while the corp token was fetched with a different agent's secret; caching per-agent tickets under keys that collide after agentId changes; stale cached access_token after credential rotation.","solutions":["Read the errcode from the embedded JSON body in the exception message","Verify the corpsecret used for access_token belongs to agentId passed to getAgentTicket()","Flush cached access_token and the per-agent ticket key (getKey() . '.' . $agentId) and retry","Confirm the agent has JS-SDK permission and the page domain is set as trusted domain for that agent"],"exampleFix":"// before\n$ticket = $work->jsapi_ticket->getAgentTicket(1000002); // secret from agent 1000001\n// after - fetch token with the same agent's secret\n$config = ['corp_id' => 'ww1234', 'secret' => $secretOfAgent1000002];\n$work = new \\EasyWeChat\\Work\\Application($config);\n$ticket = $work->jsapi_ticket->getAgentTicket(1000002);","handlingStrategy":"try-catch","validationCode":"$agentSecrets = loadAgentSecrets();\nif (! isset($agentSecrets[$agentId])) { throw new \\InvalidArgumentException(\"no secret for agent {$agentId}\"); }","typeGuard":null,"tryCatchPattern":"use EasyWeChat\\Kernel\\Exceptions\\HttpException;\ntry {\n    $ticket = $work->jsapi_ticket->getAgentTicket($agentId);\n} catch (HttpException $e) {\n    // clear per-agent ticket + access token, ensure the token was built with THIS agent's secret\n    $work->jsapi_ticket->cache->delete($work->jsapi_ticket->getAgentKey($agentId));\n    $ticket = $work->jsapi_ticket->getAgentTicket($agentId);\n}","preventionTips":["One Application per agent, or always derive the token from the same agentId you request the ticket for","Verify the agent's trusted domain includes the page origin","Cache agent tickets under their per-agent key only"],"tags":["wechat-work","jsapi-ticket","agent-config","js-sdk","access-token"],"backgroundTag":"jsapi-ticket-request-failed","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}