w7corp/easywechat · error · InvalidArgumentException
Invalid Response content "%s".
Error message
Invalid Response content "%s".
What it means
createJsonResponse() json_encodes the reply attributes and throws this InvalidArgumentException when json_encode returns false. Encoding fails on malformed UTF-8 byte sequences and on NAN/INF values, so the usual culprit is reply content containing non-UTF-8 text (GBK/Latin-1 from a legacy database) or binary data. Note the message itself does implode(',', $attributes), which cannot render nested arrays.
Source
Thrown at src/Kernel/Traits/RespondJsonMessage.php:59
}
throw new InvalidArgumentException(
sprintf('Invalid Response type "%s".', gettype($response))
);
}
/**
* @throws RuntimeException
*/
protected function createJsonResponse(array $attributes, ?Encryptor $encryptor = null): ResponseInterface
{
$jsonStr = json_encode($attributes, JSON_UNESCAPED_UNICODE);
if (is_string($jsonStr)) {
return new Response(200, ['Content-Type' => 'application/json'], $encryptor ? $encryptor->encrypt($jsonStr, messageType: $this->messageType) : $jsonStr);
}
throw new InvalidArgumentException(
sprintf('Invalid Response content "%s".', implode(',', $attributes))
);
}
}
View on GitHub (pinned to f0cf0a8b83)
Solutions
- Normalize reply text to UTF-8: mb_convert_encoding($text, 'UTF-8', 'GBK').
- Strip invalid sequences: iconv('UTF-8', 'UTF-8//IGNORE', $text).
- Keep floats out or guard with is_finite() before returning the reply.
- Never put binary in a passive reply — reply with a download link instead.
Example fix
// before: user text in GBK reaches the reply return ['msgtype' => 'text', 'text' => ['content' => $userInput]]; // after: normalize to UTF-8 before replying return ['msgtype' => 'text', 'text' => ['content' => mb_convert_encoding($userInput, 'UTF-8', 'GBK')]];
Defensive patterns
Strategy: validation
Validate before calling
array_walk_recursive($reply, function (&$v): void {
if (is_string($v) && !mb_check_encoding($v, 'UTF-8')) { $v = mb_convert_encoding($v, 'UTF-8', 'GBK,UTF-8'); }
if (is_float($v) && !is_finite($v)) { $v = 0; }
}); Type guard
function isUtf8JsonEncodable(array $reply): bool { $ok = true; array_walk_recursive($reply, function ($v) use (&$ok) { if (is_string($v)) { $ok = $ok && mb_check_encoding($v, 'UTF-8'); } }); return $ok; } Try / catch
try { return $server->serve(); } catch (\EasyWeChat\Kernel\Exceptions\InvalidArgumentException $e) { if (str_contains($e->getMessage(), 'Invalid Response content')) { \Log::warning('reply not JSON-encodable, falling back to success'); return new \Nyholm\Psr7\Response(200, [], 'success'); } throw $e; } Prevention
- Make UTF-8 the single internal encoding
- Validate external text at the boundary with mb_check_encoding
- Never place raw file bytes in passive replies
When it happens
Trigger: A Work JSON-mode passive reply whose text was stored or converted as GBK; echoing raw uploaded bytes into a reply; a division producing NAN/INF floats that end up in the payload.
Common situations: Databases with latin1/gbk columns feeding reply content; upstream systems sending unvalidated user text; debug strings appended to replies.
Related errors
- -40012
- The type of `json` must be string or array.
- Failed to decode content. Content must be valid XML or JSON.
- msgtype cannot be empty.
- Invalid Response type "%s".
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/ce34cbc67364947b.
Report an issue: GitHub.