airbnb/lottie-android · error · JsonEncodingException
JSON forbids NaN and infinities: {} at path {}
Error message
JSON forbids NaN and infinities: {} at path {} What it means
Thrown by nextDouble() when the parsed double value is NaN or Infinity and the reader is in strict (non-lenient) mode. Per the JSON specification (RFC 8259), NaN and Infinity are not valid JSON number literals — they are unquoted identifiers that strict parsers reject. Moshi enforces this unless setLenient(true) was called.
Source
Thrown at lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java:690
peekedString = nextQuotedValue(DOUBLE_QUOTE_OR_SLASH);
} else if (p == PEEKED_SINGLE_QUOTED) {
peekedString = nextQuotedValue(SINGLE_QUOTE_OR_SLASH);
} else if (p == PEEKED_UNQUOTED) {
peekedString = nextUnquotedValue();
} else if (p != PEEKED_BUFFERED) {
throw new JsonDataException("Expected a double but was " + peek() + " at path " + getPath());
}
peeked = PEEKED_BUFFERED;
double result;
try {
result = Double.parseDouble(peekedString);
} catch (NumberFormatException e) {
throw new JsonDataException("Expected a double but was " + peekedString
+ " at path " + getPath());
}
if (!lenient && (Double.isNaN(result) || Double.isInfinite(result))) {
throw new JsonEncodingException("JSON forbids NaN and infinities: " + result
+ " at path " + getPath());
}
peekedString = null;
peeked = PEEKED_NONE;
pathIndices[stackSize - 1]++;
return result;
}
/**
* Returns the string up to but not including {@code quote}, unescaping any character escape
* sequences encountered along the way. The opening quote should have already been read. This
* consumes the closing quote, but does not include it in the returned string.
*
* @throws IOException if any unicode escape sequences are malformed.
*/
private String nextQuotedValue(ByteString runTerminator) throws IOException {
StringBuilder builder = null;
while (true) {View on GitHub (pinned to 05ea92e903)
Solutions
- Find the NaN/Infinity value in the JSON at the reported path and replace it with a valid finite number (e.g., 0.0 or the correct animation value)
- Re-export from After Effects ensuring no expression evaluates to NaN/Infinity
- If you control the JSON generation, sanitize: replace Double.isNaN/isInfinite values with 0.0 before serialization
- If you must accept these, set the reader to lenient mode — but note Lottie's internal parser controls this and strict mode is intentional
Example fix
// before: {"s": [{"x": Infinity, "y": NaN}]}
// after: {"s": [{"x": 1.0, "y": 0.0}]}
// if generating JSON yourself, sanitize before serializing:
double safeVal = (Double.isNaN(val) || Double.isInfinite(val)) ? 0.0 : val; Defensive patterns
Strategy: validation
Validate before calling
// Sanitize NaN/Infinity values before loading
String sanitizeJson(String json) {
// Replace bare NaN and Infinity tokens with 0
return json
.replaceAll("(?<![\\w\"])\\bNaN\\b(?![\\w\"])", "0")
.replaceAll("(?<![\\w\"])-?\\bInfinity\\b(?![\\w\"])", "0");
}
// Usage:
String cleanJson = sanitizeJson(rawJson);
LottieCompositionFactory.fromJsonData(cleanJson, cacheKey); Try / catch
try {
LottieCompositionFactory.fromJsonData(jsonData, cacheKey);
} catch (JsonEncodingException e) {
// JSON forbids NaN and infinities
Log.w(TAG, "Invalid numeric value in Lottie JSON: " + e.getMessage());
// attempt to sanitize and retry, or fall back
showFallbackAnimation();
} Prevention
- Ensure After Effects expressions never evaluate to NaN or Infinity before export
- If generating Lottie JSON programmatically, sanitize special float values to 0.0 before serialization
- Pre-validate JSON for bare NaN/Infinity tokens before passing to Lottie
When it happens
Trigger: The JSON contains a bare NaN, Infinity, or -Infinity token where a double is expected, and the reader is not in lenient mode. This can also occur if a numeric literal overflows double range (e.g., 1e999) producing Infinity via Double.parseDouble. The check at JsonUtf8Reader.java:689 triggers the throw at line 690.
Common situations: A Lottie JSON file exported from a tool that serializes JavaScript's NaN/Infinity directly into the JSON. A corrupted animation property where a computed value became NaN during export. Hand-edited JSON that inserted Infinity as a placeholder. Older Bodymovin versions that didn't sanitize special float values.
Related errors
- Expected an int but was {} at path {}
- Expected a value but was {} at path {}
- End of input
- Unterminated escape sequence at path {}
- Unknown trim path type {}
AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14).
Data as JSON: /api/errors/acc01712efbcb946.
Report an issue: GitHub.