phalcon/cphalcon · error · \JsonException
json_last_error_msg()
Error message
json_last_error_msg()
What it means
Phalcon's JSON decode helper (Phalcon\Support\Helper\Json\Decode, via DecodeTrait::toDecode) wraps json_decode and converts any parse failure into a native \JsonException whose message comes from json_last_error_msg() — e.g. 'Syntax error', 'Maximum stack depth exceeded', 'Malformed UTF-8' (phalcon/Traits/Support/Helper/Json/DecodeTrait.zep:57). This guarantees JSON_THROW_ON_ERROR-like behavior even when the caller did not pass that flag.
Source
Thrown at phalcon/Traits/Support/Helper/Json/DecodeTrait.zep:57
var decoded, error, message;
/**
* Need to clear the json_last_error() before the code below
*/
let decoded = json_encode(null),
decoded = json_decode(data, associative, depth, options),
error = json_last_error(),
message = json_last_error_msg();
/**
* When JSON_THROW_ON_ERROR is set, json_decode() has already raised a
* native \JsonException above; otherwise the error is surfaced the
* same way here.
*/
if (JSON_ERROR_NONE !== error) {
json_encode(null);
throw new \JsonException(message, error);
}
return decoded;
}
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Catch \JsonException wherever the input is untrusted and fall back to a safe default.
- On PHP 8.3+, pre-validate with json_validate($json, $depth) before decoding.
- Fix the producer: encode with json_encode, send correct Content-Length, use JSON_INVALID_UTF8_SUBSTITUTE on the encode side.
Example fix
// before
$data = (new Decode())->__invoke($cookieValue); // throws JsonException on bad JSON
// after
try {
$data = (new Decode())->__invoke($cookieValue);
} catch (\JsonException $e) {
$data = [];
} Defensive patterns
Strategy: try-catch
Validate before calling
if (PHP_VERSION_ID >= 80300 && !json_validate($json)) {
$json = '{}'; // reject early with a known-good default
}
$data = (new Decode())->__invoke($json, true); Try / catch
try {
$data = (new Decode())->__invoke($payload, true);
} catch (\JsonException $e) {
$logger->warning('Invalid JSON: ' . $e->getMessage());
$data = []; // safe default for untrusted input
} Prevention
- Never hand-build JSON strings; produce it with json_encode.
- On PHP 8.3+ use json_validate() to check before decoding untrusted input.
- Pass an explicit depth when you expect deeply nested payloads instead of relying on 512.
When it happens
Trigger: Decode::__invoke($json) with truncated JSON (cookie cut off, partial HTTP body), single-quoted strings or unquoted keys, BOM/invalid UTF-8 bytes, or nesting deeper than the default 512 depth. Note UserRemember and similar consumers call this internally but catch InvalidArgumentException, so raw uses of Decode are where this surfaces.
Common situations: Reading remember-me/session cookies that were truncated or tampered with; API responses cut by proxies or timeouts; payloads stored with binary or legacy-encoded (latin1) data; hand-built JSON strings instead of json_encode output.
Related errors
- json_decode error: {message}
- json_last_error_msg()
- Configuration file {fileName} cannot be loaded
- Invalid data to validate
- JSON form schema is invalid: {detail}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/712fbfcb9c1b57ba.
Report an issue: GitHub.