phalcon/cphalcon · error · \JsonException
json_last_error_msg()
Error message
json_last_error_msg()
What it means
The JSON encode helper (Phalcon\Support\Helper\Json\Encode, via EncodeTrait::toEncode) wraps json_encode and converts failures into a native \JsonException carrying json_last_error_msg() — typical messages: 'Double INF or NaN did not resolve to a finite number', 'Recursion detected', 'Malformed UTF-8 characters, possibly incorrectly encoded' (phalcon/Traits/Support/Helper/Json/EncodeTrait.zep:55).
Source
Thrown at phalcon/Traits/Support/Helper/Json/EncodeTrait.zep:55
var encoded, error, message;
/**
* Need to clear the json_last_error() before the code below
*/
let encoded = json_encode(null),
encoded = json_encode(data, options, depth),
error = json_last_error(),
message = json_last_error_msg();
/**
* When JSON_THROW_ON_ERROR is set, json_encode() 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 (string) encoded;
}
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Sanitize first: normalize INF/NAN to 0/null, and re-encode strings with mb_convert_encoding($s, 'UTF-8', 'UTF-8') or filter invalid bytes.
- Pass JSON_INVALID_UTF8_SUBSTITUTE in the options bitmask to substitute bad bytes instead of failing.
- Catch \JsonException at the boundary and degrade gracefully (skip the cache entry, return an error payload) instead of a 500.
Example fix
// before $json = (new Encode())->__invoke(['score' => log(0)]); // -INF -> JsonException // after $payload = ['score' => is_finite($score) ? $score : 0]; $json = (new Encode())->__invoke($payload, JSON_INVALID_UTF8_SUBSTITUTE);
Defensive patterns
Strategy: try-catch
Try / catch
try {
$json = (new Encode())->__invoke($payload, JSON_INVALID_UTF8_SUBSTITUTE);
} catch (\JsonException $e) {
$logger->error('JSON encode failed: ' . $e->getMessage());
$json = null; // skip the cache entry / return error payload
} Prevention
- Normalize floats (is_finite) before encoding to avoid INF/NAN failures.
- Add JSON_INVALID_UTF8_SUBSTITUTE when data may contain legacy-charset bytes from a DB.
- Break circular references before caching layered structures; catch \JsonException at the cache/API boundary.
When it happens
Trigger: Encode::__invoke($data) on structures containing INF/NAN floats, recursive arrays/objects, resources, or strings with invalid UTF-8 (binary from a DB, latin1 data read as UTF-8).
Common situations: Encoding computed floats that hit division-by-zero yielding INF; cache layers storing layered arrays that reference themselves; DB rows in the wrong charset; binary blobs accidentally placed in an API payload.
Related errors
- json_encode 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/49783e9374a5f378.
Report an issue: GitHub.