{"record":{"id":"a91e442439c7035c","repo":"w7corp/easywechat","slug":"token-or-aes-key-cannot-be-empty","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/MiniApp/Application.php","lineNumber":82,"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":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/MiniApp/Application.php#L64-L100","documentation":"MiniApp\\Application::getEncryptor() builds the message-push Encryptor from the account's token and aes_key and throws this InvalidConfigException when either is empty. It is reached directly via $app->getEncryptor(), and indirectly from getServer() whenever an aes_key is configured but the token is missing (src/MiniApp/Application.php:108).","triggerScenarios":"Mini app config containing only app_id/secret (enough for API calls) while the code path touches message push — $app->getServer()->serve(), encrypted replies, or getEncryptor(); token set but aes_key empty or vice versa; keys present under wrong names ('aesKey' instead of 'aes_key').","commonSituations":"Starting with login/payment flows and later adding push notifications without updating config; copying config arrays between OfficialAccount and MiniApp apps with different key names; env vars not loaded in the worker/fpm runtime executing the callback.","solutions":["Set both 'token' and 'aes_key' (the 43-char EncodingAESKey) in the MiniApp config, matching 开发管理-消息推送 in the mini program console.","Check the exact snake_case key names: token, aes_key.","If you do not use message push, avoid getServer()/getEncryptor() code paths.","Verify env loading in the exact runtime that serves the callback (queue worker, fpm, octane)."],"exampleFix":"// before: login-only config\n$app = new MiniApp\\Application(['app_id' => $id, 'secret' => $secret]);\n$app->getServer()->serve(); // throws\n// after: add push credentials from the console\n$app = new MiniApp\\Application([\n    'app_id' => $id, 'secret' => $secret,\n    'token' => env('MINIAPP_TOKEN'),\n    'aes_key' => env('MINIAPP_AES_KEY'),\n]);","handlingStrategy":"validation","validationCode":"if (strlen((string) ($config['aes_key'] ?? '')) !== 43 || trim((string) ($config['token'] ?? '')) === '') { throw new RuntimeException('MiniApp push requires token and the 43-char aes_key (EncodingAESKey)'); }","typeGuard":null,"tryCatchPattern":"try { $encryptor = $app->getEncryptor(); } catch (\\EasyWeChat\\Kernel\\Exceptions\\InvalidConfigException $e) { throw new RuntimeException('MiniApp push credentials missing: set token and aes_key from the console', 0, $e); }","preventionTips":["Keep a config template listing token and aes_key with expected lengths","Feature-flag push routes until credentials exist","Validate push credentials at boot when push is enabled"],"tags":["php","miniapp","config","message-push"],"backgroundTag":"missing-configuration","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}