{"record":{"id":"3db40611077bbb71","repo":"w7corp/easywechat","slug":"no-secret-configured","errorCode":null,"errorMessage":"No secret configured.","messagePattern":"No secret configured\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/OfficialAccount/Account.php","lineNumber":31,"sourceCode":"        protected string $appId,\n        protected ?string $secret,\n        protected ?string $token = null,\n        protected ?string $aesKey = null\n    ) {\n    }\n\n    public function getAppId(): string\n    {\n        return $this->appId;\n    }\n\n    /**\n     * @throws RuntimeException\n     */\n    public function getSecret(): string\n    {\n        if ($this->secret === null) {\n            throw new RuntimeException('No secret configured.');\n        }\n\n        return $this->secret;\n    }\n\n    public function getToken(): ?string\n    {\n        return $this->token;\n    }\n\n    public function getAesKey(): ?string\n    {\n        return $this->aesKey;\n    }\n}\n","sourceCodeStart":13,"sourceCodeEnd":47,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/OfficialAccount/Account.php#L13-L47","documentation":"OfficialAccount\\Account::getSecret() throws this RuntimeException when the Account object was constructed with secret = null. It is a fail-fast config guard: EasyWeChat refuses to run API flows that need the app secret (OAuth client_secret, token requests) rather than send empty credentials. Since Application::getAccount() reads the 'secret' config key, the exception in practice appears when an Account was built or injected without one.","triggerScenarios":"$app->setAccount(new Account(appId: 'wx...')) with no secret, followed by $app->getOAuth() (whose default factory passes getSecret() as client_secret); a custom Account implementation returning null from getSecret().","commonSituations":"Reusing an API-only config (app_id plus token) for a page that starts OAuth; hand-built Account objects in constructors or DI containers; test doubles replacing the Account; secret loaded from an env var that is unset in the deployed environment.","solutions":["Provide the secret: new Account(appId: $appId, secret: $secret), or set the 'secret' key in the Application config array","Check the env var name/value in the failing environment and clear the config cache after fixing it","If the app intentionally has no secret, avoid the OAuth/token surfaces that call getSecret()"],"exampleFix":"// before\n$app->setAccount(new \\EasyWeChat\\OfficialAccount\\Account(appId: 'wx1234'));\n$provider = $app->getOAuth(); // RuntimeException: No secret configured.\n\n// after\n$app->setAccount(new \\EasyWeChat\\OfficialAccount\\Account(\n    appId: 'wx1234',\n    secret: env('WECHAT_OFFICIAL_ACCOUNT_SECRET')\n));","handlingStrategy":"validation","validationCode":"$secret = $app->getConfig()->get('secret');\nif ($secret === null || trim((string) $secret) === '') {\n    throw new \\RuntimeException('OfficialAccount \"secret\" is required before OAuth/token APIs are used.');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $secret = $app->getAccount()->getSecret();\n} catch (\\RuntimeException $e) {\n    throw new \\RuntimeException('OfficialAccount misconfigured: set \"secret\" in the config/Account.', 0, $e);\n}","preventionTips":["Fail fast at boot: assert app_id and secret are non-empty before serving traffic","Keep WeChat credentials in env vars and validate them in a config/health-check command","Do not hand-build Account objects without the secret"],"tags":["php","easywechat","wechat","official-account","config","oauth"],"backgroundTag":"missing-required-config","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}