w7corp/easywechat · error · RuntimeException
No secret configured.
Error message
No secret configured.
What it means
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.
Source
Thrown at src/OfficialAccount/Account.php:31
protected string $appId,
protected ?string $secret,
protected ?string $token = null,
protected ?string $aesKey = null
) {
}
public function getAppId(): string
{
return $this->appId;
}
/**
* @throws RuntimeException
*/
public function getSecret(): string
{
if ($this->secret === null) {
throw new RuntimeException('No secret configured.');
}
return $this->secret;
}
public function getToken(): ?string
{
return $this->token;
}
public function getAesKey(): ?string
{
return $this->aesKey;
}
}
View on GitHub (pinned to f0cf0a8b83)
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()
Example fix
// before
$app->setAccount(new \EasyWeChat\OfficialAccount\Account(appId: 'wx1234'));
$provider = $app->getOAuth(); // RuntimeException: No secret configured.
// after
$app->setAccount(new \EasyWeChat\OfficialAccount\Account(
appId: 'wx1234',
secret: env('WECHAT_OFFICIAL_ACCOUNT_SECRET')
)); Defensive patterns
Strategy: validation
Validate before calling
$secret = $app->getConfig()->get('secret');
if ($secret === null || trim((string) $secret) === '') {
throw new \RuntimeException('OfficialAccount "secret" is required before OAuth/token APIs are used.');
} Try / catch
try {
$secret = $app->getAccount()->getSecret();
} catch (\RuntimeException $e) {
throw new \RuntimeException('OfficialAccount misconfigured: set "secret" in the config/Account.', 0, $e);
} Prevention
- 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
When it happens
Trigger: $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().
Common situations: 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.
Related errors
- token or aes_key cannot be empty.
- The token is required to validate the request signature, ple
- Failed to get stable access_token: %s
- Failed to get access_token: %s
- Failed to get jssdk ticket: %s
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/3db40611077bbb71.
Report an issue: GitHub.