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

  1. Provide the secret: new Account(appId: $appId, secret: $secret), or set the 'secret' key in the Application config array
  2. Check the env var name/value in the failing environment and clear the config cache after fixing it
  3. 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

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


AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21). Data as JSON: /api/errors/3db40611077bbb71. Report an issue: GitHub.