{"record":{"id":"8ad014bf4f422cd6","repo":"octobercms/october","slug":"system-lang-server-response-invalid-8ad014","errorCode":"system::lang.server.response_invalid","errorMessage":"Invalid response from the server.","messagePattern":"Invalid response from the server\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"warning","filePath":"modules/system/classes/updatemanager/ManagesModules.php","lineNumber":193,"sourceCode":"        $contents = $result->body();\n\n        if ($result->status() === 404) {\n            throw new ApplicationException(Lang::get('system::lang.server.response_empty'));\n        }\n\n        if ($result->status() !== 200) {\n            throw new ApplicationException(\n                strlen($contents)\n                ? $contents\n                : Lang::get('system::lang.server.response_empty')\n            );\n        }\n\n        try {\n            $resultData = json_decode($contents, true);\n        }\n        catch (Exception $ex) {\n            throw new ApplicationException(Lang::get('system::lang.server.response_invalid'));\n        }\n\n        return $resultData;\n    }\n\n    /**\n     * getBuildFromVersion will return the patch version of a semver string\n     * eg: 1.2.3 -> 3, 1.2.3-dev -> 3\n     */\n    protected function getBuildFromVersion(string $version): int\n    {\n        $parts = explode('.', $version);\n        if (count($parts) !== 3) {\n            return 0;\n        }\n\n        $lastPart = $parts[2];\n        if (!is_numeric($lastPart)) {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/classes/updatemanager/ManagesModules.php#L175-L211","documentation":"requestChangelog() wraps json_decode($contents, true) in try/catch and throws 'Invalid response from the server' (response_invalid) when decoding fails. The changelog endpoint returned HTTP 200 but a body that is not valid JSON — typically an HTML page, a truncated response, or injected content. Note the quirk: unlike the JSON-path code in HasGatewayAccess, there is no post-decode emptiness check, so only a hard decode failure triggers this.","triggerScenarios":"Changelog request answered with 200 + HTML (captive portal, error template with 200 status, proxy interstitial); body corrupted in transit; any backend view that calls requestChangelog().","commonSituations":"Captive/filtered networks rewriting responses; WAF or ad-injection middleware appending content; custom environments pointing the changelog host elsewhere; partial responses from flaky TLS middleboxes.","solutions":["Fetch the changelog URL manually and confirm it returns pure JSON","Remove HTML-injecting middleware (WAF pages, proxies, captive portals) from the path to octobercms.com","Check for output corruption: BOM, leading whitespace, or appended scripts in the raw body","Update the CMS if running an old build whose changelog URL/format predates current octobercms.com"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $changelog = \\System\\Classes\\UpdateManager::instance()->requestChangelog();\n} catch (\\October\\Rain\\Exception\\ApplicationException $ex) {\n    if (str_contains($ex->getMessage(), 'Invalid response')) {\n        // 200 + non-JSON body — likely a proxy/portal injecting HTML\n        Log::warning('Changelog payload was not JSON');\n        $changelog = [];\n    } else {\n        throw $ex;\n    }\n}","preventionTips":["Ensure nothing (WAF, proxy, captive portal) rewrites bodies from octobercms.com","Log raw bodies on decode failures once, to identify the injected content","Don't assume 200 means success — validate JSON before use in your own gateway clients too"],"tags":["octobercms","updates","changelog","json","invalid-response"],"backgroundTag":"invalid-json-response","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}