airbnb/lottie-android · error · JsonDataException
Expected a value but was {} at path {}
Error message
Expected a value but was {} at path {} What it means
Thrown during skipValue() when a closing array bracket `]` (PEEKED_END_ARRAY) is encountered but the internal nesting counter has already reached zero (count < 0 at line 850). This means the JSON has an unbalanced bracket — there are more closing brackets than opening ones in the current scope being skipped.
Source
Thrown at lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java:851
throw new JsonDataException("Cannot skip unexpected " + peek() + " at " + getPath());
}
int count = 0;
do {
int p = peeked;
if (p == PEEKED_NONE) {
p = doPeek();
}
if (p == PEEKED_BEGIN_ARRAY) {
pushScope(JsonScope.EMPTY_ARRAY);
count++;
} else if (p == PEEKED_BEGIN_OBJECT) {
pushScope(JsonScope.EMPTY_OBJECT);
count++;
} else if (p == PEEKED_END_ARRAY) {
count--;
if (count < 0) {
throw new JsonDataException(
"Expected a value but was " + peek() + " at path " + getPath());
}
stackSize--;
} else if (p == PEEKED_END_OBJECT) {
count--;
if (count < 0) {
throw new JsonDataException(
"Expected a value but was " + peek() + " at path " + getPath());
}
stackSize--;
} else if (p == PEEKED_UNQUOTED_NAME || p == PEEKED_UNQUOTED) {
skipUnquotedValue();
} else if (p == PEEKED_DOUBLE_QUOTED || p == PEEKED_DOUBLE_QUOTED_NAME) {
skipQuotedValue(DOUBLE_QUOTE_OR_SLASH);
} else if (p == PEEKED_SINGLE_QUOTED || p == PEEKED_SINGLE_QUOTED_NAME) {
skipQuotedValue(SINGLE_QUOTE_OR_SLASH);
} else if (p == PEEKED_NUMBER) {
buffer.skip(peekedNumberLength);View on GitHub (pinned to 05ea92e903)
Solutions
- Validate the JSON with a JSON linter or parser (e.g., jsonlint.com, or org.json in Java) before passing it to Lottie to detect structural errors
- Re-export the animation from After Effects to regenerate a well-formed JSON
- If the JSON is truncated, ensure the full file is downloaded/read before parsing — check network integrity and file completeness
- Catch JsonDataException during composition loading and show a fallback or error UI
Example fix
// before: {"k": [1, 2, 3]]} // extra closing bracket
// after: {"k": [1, 2, 3]} Defensive patterns
Strategy: validation
Validate before calling
// Validate JSON structure balance before passing to Lottie
boolean isJsonStructurallyValid(String json) {
try {
new org.json.JSONObject(json); // or JSONArray if top-level is array
return true;
} catch (org.json.JSONException e) {
// try as array
try {
new org.json.JSONArray(json);
return true;
} catch (org.json.JSONException e2) {
return false;
}
}
} Try / catch
try {
LottieCompositionFactory.fromJsonData(jsonData, cacheKey);
} catch (JsonDataException e) {
Log.w(TAG, "Structural error in Lottie JSON: " + e.getMessage());
showFallbackAnimation();
} Prevention
- Validate JSON with org.json or Gson before passing to Lottie
- Ensure animation files are fully downloaded and not truncated
- Re-export from After Effects if the JSON is structurally corrupt
When it happens
Trigger: skipValue() is iterating through tokens and hits PEEKED_END_ARRAY when count is already 0. This happens when the JSON structure is malformed: an extra `]` appears, or a value was being skipped at the top level and the document structure is broken. The throw occurs at line 851.
Common situations: A truncated or corrupted Lottie JSON file where an array's closing bracket appears without a matching opening bracket. A minified JSON with missing brackets due to a transmission or encoding error. A Bodymovin plugin bug producing malformed array structures. Manual editing that removed an opening `[` but left the closing `]`.
Related errors
- Unknown point starts with {}
- Unknown value for token of type {}
- Cannot convert json to point. Next token is {}
- {} at path {}
- JSON forbids NaN and infinities: {} at path {}
AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14).
Data as JSON: /api/errors/d3a3dd8da2fd1391.
Report an issue: GitHub.