{"record":{"id":"440d5b349c410bd2","repo":"w7corp/easywechat","slug":"invalid-response-type-s-440d5b","errorCode":null,"errorMessage":"Invalid Response type \"%s\".","messagePattern":"Invalid Response type \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Kernel/Traits/RespondXmlMessage.php","lineNumber":78,"sourceCode":"            foreach ($response as $key => $value) {\n                $normalized[(string) $key] = $value;\n            }\n\n            if (! isset($normalized['MsgType'])) {\n                throw new InvalidArgumentException('MsgType cannot be empty.');\n            }\n\n            return $normalized;\n        }\n\n        if (is_string($response) || is_numeric($response)) {\n            return [\n                'MsgType' => 'text',\n                'Content' => $response,\n            ];\n        }\n\n        throw new InvalidArgumentException(\n            sprintf('Invalid Response type \"%s\".', gettype($response))\n        );\n    }\n\n    /**\n     * @param  array<string, mixed>  $attributes\n     *\n     * @throws RuntimeException\n     */\n    protected function createXmlResponse(array $attributes, ?Encryptor $encryptor = null): ResponseInterface\n    {\n        $xml = Xml::build($attributes);\n\n        return new Response(200, ['Content-Type' => 'application/xml'], $encryptor ? $encryptor->encrypt($xml) : $xml);\n    }\n}\n","sourceCodeStart":60,"sourceCodeEnd":95,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/Kernel/Traits/RespondXmlMessage.php#L60-L95","documentation":"XML-mode normalizeResponse() accepts arrays, strings and numerics (strings/numerics become text replies) and throws on everything else, naming gettype in the message. Objects, resources and true from a handler hit this path; null and '' are treated as empty by transformToReply() and answered with the automatic 'success' response, so they never throw.","triggerScenarios":"A handler returns true (a 'handled' flag), an object such as the incoming Message instance, a DTO/ArrayObject, or a resource; passthrough handlers doing return $message;.","commonSituations":"Middleware pipelines whose handlers return booleans; returning Laravel models or value objects from business code; returning the result of a void-ish API that is an object.","solutions":["Return a string, an array, or a PSR ResponseInterface from reply handlers.","For 'handled, no reply', return null or '' — the SDK replies 'success'.","Cast or restructure boolean-returning helpers so the reply chain yields a supported type."],"exampleFix":"// before: boolean return\npublic function __invoke($message, $next) { $this->process($message); return true; }\n// after: empty return means the automatic 'success' no-op reply\npublic function __invoke($message, $next) { $this->process($message); return ''; }","handlingStrategy":"validation","validationCode":"if (is_object($reply) || is_bool($reply) || is_resource($reply)) { $reply = ''; }","typeGuard":"function isAcceptableXmlReply(mixed $r): bool { return $r === null || $r === '' || is_string($r) || is_numeric($r) || is_array($r) || $r instanceof \\Psr\\Http\\Message\\ResponseInterface; }","tryCatchPattern":"try { return $server->serve(); } catch (\\EasyWeChat\\Kernel\\Exceptions\\InvalidArgumentException $e) { if (str_contains($e->getMessage(), 'Invalid Response type')) { \\Log::warning('handler returned unsupported reply type'); return new \\Nyholm\\Psr7\\Response(200, [], 'success'); } throw $e; }","preventionTips":["Document handler contracts as string|array|ResponseInterface|null","Avoid boolean returns inside reply chains","Add static analysis annotations for handler return types"],"tags":["php","xml-reply","return-type","message-push"],"backgroundTag":"invalid-response-format","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}