{"record":{"id":"50e23fad94ae88de","repo":"phalcon/cphalcon","slug":"json-decode-error-message","errorCode":null,"errorMessage":"json_decode error: {message}","messagePattern":"json_decode error: (.+?)","errorType":"exception","errorClass":"Phalcon\\Support\\Helper\\Json\\Exceptions\\JsonDecodeError","httpStatus":null,"severity":"error","filePath":"phalcon/Support/Helper/Json/Decode.zep","lineNumber":51,"sourceCode":"\n    /**\n     * @param int<1, max> $depth       Recursion depth.\n     *\n     * @throws JsonDecodeError if the JSON cannot be decoded.\n     * @link https://www.php.net/manual/en/function.json-decode.php\n     */\n    public function __invoke(\n        string data,\n        bool associative = false,\n        int depth = 512,\n        int options = 79\n    ) {\n        var ex;\n\n        try {\n            return this->toDecode(data, associative, depth, options);\n        } catch JsonException, ex {\n            throw new JsonDecodeError(ex->getMessage(), ex->getCode(), ex);\n        }\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":55,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Support/Helper/Json/Decode.zep#L33-L55","documentation":"Phalcon\\Support\\Helper\\Json\\Decode wraps json_decode with throw-on-error semantics and rethrows any JsonException as Phalcon\\Support\\Helper\\Json\\Exceptions\\JsonDecodeError (\"json_decode error: {message}\"), preserving the code and the previous exception. It fires for exactly the reasons json_decode() fails: syntax errors, unexpected tokens, or nesting deeper than the $depth argument (default 512). Also reachable via HelperFactory as 'jsonDecode'.","triggerScenarios":"(new Decode())('{\"a\":') or $helpers->jsonDecode($raw) where $raw is an HTML error page from an upstream API ('Syntax error'); a JSON body truncated by a size limit; nesting beyond 512 levels.","commonSituations":"Remote APIs returning HTML or empty bodies on 5xx, gateway error pages, BOM-prefixed UTF-8 exports, payloads cut off by proxy/body-size limits, strings with smart quotes pasted into 'JSON' files.","solutions":["Validate before decoding: json_validate($raw) on PHP >= 8.3, or a decode-and-check-json_last_error probe","Check the upstream response status and Content-Type before treating the body as JSON","Pass a larger $depth for deeply nested documents","Strip BOM/whitespace: $raw = preg_replace('/^\\xEF\\xBB\\xBF/', '', trim($raw));"],"exampleFix":"// before\n$data = (new Decode())($response->getBody()); // 'json_decode error: Syntax error'\n\n// after\n$raw = trim($response->getBody());\nif (json_validate($raw)) { // PHP 8.3+\n    $data = (new Decode())($raw);\n} else {\n    $logger->error('Non-JSON body: ' . substr($raw, 0, 200));\n    $data = [];\n}","handlingStrategy":"validation","validationCode":"$raw = trim($response->getBody());\n\nif (json_validate($raw)) { // PHP 8.3+; older: decode + json_last_error check\n    $data = (new Decode())($raw);\n} else {\n    $logger->error('Non-JSON body: ' . substr($raw, 0, 200));\n    $data = [];\n}","typeGuard":"function isJsonString(string $raw): bool\n{\n    json_decode($raw);\n\n    return JSON_ERROR_NONE === json_last_error();\n}","tryCatchPattern":"use Phalcon\\Support\\Helper\\Json\\Exceptions\\JsonDecodeError;\n\ntry {\n    $data = $decode($raw);\n} catch (JsonDecodeError $e) {\n    // \"json_decode error: Syntax error\" etc.; previous holds the JsonException\n    $data = null;\n    $logger->error($e->getMessage());\n}","preventionTips":["Assert Content-Type: application/json and a success status before decoding remote bodies","json_validate() first when targeting PHP 8.3+","Log a payload snippet on failure — truncation and HTML error pages are the most common causes","Pass $depth explicitly for deeply nested documents"],"tags":["phalcon","json","decode","php"],"backgroundTag":"json-decode-syntax-error","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}