airbnb/lottie-android · error · EOFException
Unterminated escape sequence at path {}
Error message
Unterminated escape sequence at path {} What it means
Thrown by readEscapeCharacter() when a `\u` escape sequence is encountered but fewer than 4 hexadecimal digits follow before the input ends. JSON unicode escapes require exactly 4 hex digits (e.g., \u0041 for 'A'). The check `source.request(4)` at line 995 fails when the stream doesn't have 4 more bytes, and an EOFException is thrown at line 996.
Source
Thrown at lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java:996
}
/**
* Unescapes the character identified by the character or characters that immediately follow a
* backslash. The backslash '\' should have already been read. This supports both unicode escapes
* "u000A" and two-character escapes "\n".
*
* @throws IOException if any unicode escape sequences are malformed.
*/
private char readEscapeCharacter() throws IOException {
if (!source.request(1)) {
throw syntaxError("Unterminated escape sequence");
}
byte escaped = buffer.readByte();
switch (escaped) {
case 'u':
if (!source.request(4)) {
throw new EOFException("Unterminated escape sequence at path " + getPath());
}
// Equivalent to Integer.parseInt(stringPool.get(buffer, pos, 4), 16);
char result = 0;
for (int i = 0, end = i + 4; i < end; i++) {
byte c = buffer.getByte(i);
result <<= 4;
if (c >= '0' && c <= '9') {
result += (c - '0');
} else if (c >= 'a' && c <= 'f') {
result += (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
result += (c - 'A' + 10);
} else {
throw syntaxError("\\u" + buffer.readUtf8(4));
}
}
buffer.skip(4);
return result;View on GitHub (pinned to 05ea92e903)
Solutions
- Search the JSON for \u sequences and verify each has exactly 4 hexadecimal digits (0-9, A-F, a-f) following it
- Re-export the animation from After Effects to regenerate valid escapes
- If the file is truncated, re-download or re-export to ensure completeness
- Pre-validate the JSON with a strict JSON parser (e.g., org.json.JSONObject) which will catch malformed escapes before Lottie attempts parsing
Example fix
// before: {"t": "Hello\u00 World} // \u00 has only 2 hex digits, and missing closing quote
// after: {"t": "Hello\u0041 World} // \u0041 = 'A', 4 valid hex digits Defensive patterns
Strategy: validation
Validate before calling
// Validate unicode escape sequences in the JSON
boolean hasValidUnicodeEscapes(String json) {
java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\\\u([0-9a-fA-F]{4})");
java.util.regex.Pattern partial = java.util.regex.Pattern.compile("\\\\u(?![0-9a-fA-F]{4})");
if (partial.matcher(json).find()) {
return false; // found a truncated \u escape
}
return true;
}
// Usage:
if (!hasValidUnicodeEscapes(jsonData)) {
Log.e(TAG, "JSON contains malformed unicode escape");
showFallback();
} Try / catch
try {
LottieCompositionFactory.fromJsonData(jsonData, cacheKey);
} catch (EOFException e) {
Log.w(TAG, "Truncated escape sequence in Lottie JSON: " + e.getMessage());
showFallbackAnimation();
} Prevention
- Validate JSON with a standard parser before passing to Lottie — it will catch malformed escapes
- Re-export animations from After Effects to regenerate valid unicode escapes
- Check for file truncation if the JSON was downloaded or transferred
When it happens
Trigger: A JSON string value contains a \u escape that is truncated — e.g., "\u00" (only 2 digits), "\u" (no digits), or the input stream ends right after \u. The readEscapeCharacter method at line 994 checks for the 'u' escape type, then at line 995 requests 4 bytes; if fewer are available, the throw at line 996 fires.
Common situations: A Lottie animation JSON with a text layer containing a malformed unicode escape (e.g., from a text expression that generated an invalid escape). A truncated JSON file cut off mid-escape. A file encoding or transfer issue that corrupted a multi-byte escape sequence. A minifier or compressor that incorrectly truncated unicode escapes.
Related errors
- JSON forbids NaN and infinities: {} at path {}
- Expected an int but was {} at path {}
- Expected a value but was {} at path {}
- End of input
- Unknown trim path type {}
AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14).
Data as JSON: /api/errors/9cc1794fb1c329d0.
Report an issue: GitHub.