w7corp/easywechat · error · InvalidConfigException
The token is required to validate the request signature…
Error message
The token is required to validate the request signature, please pass it to the server or configure the `token` of the application.
What it means
Server::getToken() resolves the callback token as the explicitly passed constructor token or falls back to the encryptor's token; when both are empty it throws InvalidConfigException because signature validation of inbound requests (signature/msg_signature) is impossible without it. Built from the Application, the token comes from the 'token' config key, so token-less API-only setups hit this on the first callback.
Solutions
- Set 'token' in the Application config to the value configured in the MP console server config
- Or pass token (or an encryptor, which carries one) explicitly when constructing the Server
- Clear the config cache and confirm the env var reaches the process (config:show / dump env)
Example fix
// before
$config = ['app_id' => 'wx1234', 'secret' => '...'];
$app = new \EasyWeChat\OfficialAccount\Application($config);
$app->getServer()->serve(); // InvalidConfigException: token required
// after
$config = ['app_id' => 'wx1234', 'secret' => '...',
'token' => env('WECHAT_TOKEN'), 'aes_key' => env('WECHAT_AES_KEY')];
$app = new \EasyWeChat\OfficialAccount\Application($config);
$app->getServer()->serve(); Defensive patterns
Strategy: validation
Validate before calling
if (blank($app->getConfig()->get('token'))) {
abort(503, 'callback endpoint active but WECHAT token not configured');
} Try / catch
try {
return $app->getServer()->serve();
} catch (\EasyWeChat\Kernel\Exceptions\InvalidConfigException $e) {
// serve() cannot validate signatures without a token: fail loudly, do not 200 'success'
return new \Nyholm\Psr7\Response(503, [], 'server misconfigured');
} Prevention
- Add 'token' to config the moment a callback route exists, even if encryption is off
- Assert required WeChat keys in a boot-time config check per environment
- Never return 200 from a webhook whose signature validation could not run
When it happens
Trigger: $app->getServer()->serve() (or echostr verification via validatePlainRequest()) on an Application whose config lacks 'token'; a manually constructed Server given neither token nor encryptor.
Common situations: A webhook route added to a project that previously only made outbound API calls; production .env missing WECHAT_TOKEN while local has it; refactors that construct the Server directly and drop the token argument.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Encrypted message is required, plaintext message rejected.
- No secret configured.
- token or aes_key cannot be empty.
- Failed to get access_token
- Failed to get jssdk ticket
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/13c3f11c454f5352.
Report an issue: GitHub.
Appendix: source
Thrown at src/OfficialAccount/Server.php:187
protected function validatePlainRequest(array $query): void
{
$this->validatePlainSignature(
token: $this->getToken(),
signature: $this->getQueryValue($query, 'signature'),
timestamp: $this->getQueryValue($query, 'timestamp'),
nonce: $this->getQueryValue($query, 'nonce')
);
}
/**
* @throws InvalidConfigException
*/
protected function getToken(): string
{
$token = $this->token ?? $this->encryptor?->getToken();
if (empty($token)) {
throw new InvalidConfigException(
'The token is required to validate the request signature, '
.'please pass it to the server or configure the `token` of the application.'
);
}
return $token;
}
/**
* @param array<string,mixed> $query
*/
protected function decryptIncomingMessage(\EasyWeChat\Kernel\Message $message, array $query): \EasyWeChat\Kernel\Message
{
if (! $this->encryptor) {
return $message;
}
$signature = $this->getQueryValue($query, 'msg_signature');View on GitHub (pinned to f0cf0a8b83)