{"record":{"id":"e8c3873c41536b9f","repo":"w7corp/easywechat","slug":"token-or-aes-key-cannot-be-empty-e8c387","errorCode":null,"errorMessage":"token or aes_key cannot be empty.","messagePattern":"token or aes_key cannot be empty\\.","errorType":"exception","errorClass":"InvalidConfigException","httpStatus":null,"severity":"error","filePath":"src/OfficialAccount/Application.php","lineNumber":90,"sourceCode":"\n    public function setAccount(AccountInterface $account): static\n    {\n        $this->account = $account;\n\n        return $this;\n    }\n\n    /**\n     * @throws InvalidConfigException\n     */\n    public function getEncryptor(): Encryptor\n    {\n        if (! $this->encryptor) {\n            $token = $this->getAccount()->getToken();\n            $aesKey = $this->getAccount()->getAesKey();\n\n            if (empty($token) || empty($aesKey)) {\n                throw new InvalidConfigException('token or aes_key cannot be empty.');\n            }\n\n            $this->encryptor = new Encryptor(\n                appId: $this->getAccount()->getAppId(),\n                token: $token,\n                aesKey: $aesKey,\n                receiveId: $this->getAccount()->getAppId()\n            );\n        }\n\n        return $this->encryptor;\n    }\n\n    public function setEncryptor(Encryptor $encryptor): static\n    {\n        $this->encryptor = $encryptor;\n\n        return $this;","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/OfficialAccount/Application.php#L72-L108","documentation":"Application::getEncryptor() needs both token and aes_key (the EncodingAESKey) to build the Kernel Encryptor used for encrypted callback messages. If either is missing from the account it throws InvalidConfigException, because safe-mode message handling is impossible without them. The values come from the 'token' and 'aes_key' keys of the config array.","triggerScenarios":"Calling $app->getServer()->serve() (or getEncryptor()) on an Application configured with only app_id/secret while the MP console is set to secure or compatible message mode; receiving encrypted push messages after an API-only deployment.","commonSituations":"Config written for outbound API calls only, later a webhook/message route is added; EncodingAESKey copied with a typo or truncated (it is 43 characters); wrong key names ('aesKey', 'encoding_aes_key'); production .env missing the keys while local has them.","solutions":["Add both 'token' and 'aes_key' to the EasyWeChat config with the values from MP console → 基本配置","Verify the aes_key format (43-char EncodingAESKey) and that token matches the console exactly","Redeploy or clear the config cache so the new values are picked up"],"exampleFix":"// before\n$config = ['app_id' => 'wx1234', 'secret' => '...'];\n\n// after\n$config = [\n    'app_id'  => 'wx1234',\n    'secret'  => '...',\n    'token'   => env('WECHAT_TOKEN'),\n    'aes_key' => env('WECHAT_AES_KEY'),\n];","handlingStrategy":"validation","validationCode":"foreach (['token', 'aes_key'] as $key) {\n    if (blank($app->getConfig()->get($key))) {\n        throw new \\RuntimeException(\"EasyWeChat config missing '{$key}', required for encrypted callbacks.\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $app->getEncryptor();\n} catch (\\EasyWeChat\\Kernel\\Exceptions\\InvalidConfigException $e) {\n    // degrade: disable the callback route instead of serving it misconfigured\n    abort(503, 'callback encryption not configured');\n}","preventionTips":["Treat token+aes_key as required whenever a callback controller exists","Add a deploy check comparing configured token/aes_key with the MP console values","Never point message endpoints at an API-only config"],"tags":["php","easywechat","wechat","official-account","config","encryption","callback"],"backgroundTag":"missing-required-config","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}