{"record":{"id":"c868de4adc89e5ad","repo":"airbnb/lottie-android","slug":"expected-end-array-but-was-at-path","errorCode":null,"errorMessage":"Expected END_ARRAY but was {} at path {}","messagePattern":"Expected END_ARRAY but was (.+?) at path (.+?)","errorType":"exception","errorClass":"JsonDataException","httpStatus":null,"severity":"error","filePath":"lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java","lineNumber":136,"sourceCode":"      pathIndices[stackSize - 1] = 0;\n      peeked = PEEKED_NONE;\n    } else {\n      throw new JsonDataException(\"Expected BEGIN_ARRAY but was \" + peek()\n          + \" at path \" + getPath());\n    }\n  }\n\n  @Override public void endArray() throws IOException {\n    int p = peeked;\n    if (p == PEEKED_NONE) {\n      p = doPeek();\n    }\n    if (p == PEEKED_END_ARRAY) {\n      stackSize--;\n      pathIndices[stackSize - 1]++;\n      peeked = PEEKED_NONE;\n    } else {\n      throw new JsonDataException(\"Expected END_ARRAY but was \" + peek()\n          + \" at path \" + getPath());\n    }\n  }\n\n  @Override public void beginObject() throws IOException {\n    int p = peeked;\n    if (p == PEEKED_NONE) {\n      p = doPeek();\n    }\n    if (p == PEEKED_BEGIN_OBJECT) {\n      pushScope(JsonScope.EMPTY_OBJECT);\n      peeked = PEEKED_NONE;\n    } else {\n      throw new JsonDataException(\"Expected BEGIN_OBJECT but was \" + peek()\n          + \" at path \" + getPath());\n    }\n  }\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/airbnb/lottie-android/blob/05ea92e90381eb8a8ae06855ea2b74f322bebbec/lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java#L118-L154","documentation":"JsonUtf8Reader.endArray() peeks the next token and expects PEEKED_END_ARRAY (']'). If the actual token differs — for example, the stream has an extra element or the wrong delimiter — it throws JsonDataException with the actual token and current path. This fires when the parser finishes reading array elements but the JSON does not properly close the array.","triggerScenarios":"The parser expects the closing ']' of an array but encounters a different token: a missing comma producing an unexpected value, extra elements beyond what the parser consumed, or a structural corruption that shifts the reader's position.","commonSituations":"Corrupted Lottie JSON with missing or misplaced array delimiters; truncated file; JSON edited by hand with comma or bracket errors.","solutions":["Use the exception's path to locate the malformed array in the JSON and fix its structure (ensure proper brackets and commas).","Run the JSON through a standard JSON linter to catch structural errors.","Re-download or re-export the animation file."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"LottieTask<LottieComposition> task = LottieCompositionFactory.fromAsset(context, name);\ntask.addListener(result -> { /* success */ })\n     .addFailureListener(e -> { /* JSON array structure error */ });","preventionTips":["Validate Lottie JSON with a JSON linter.","Use async APIs to handle parse failures gracefully.","Re-export or re-download corrupted animations."],"tags":["lottie","json-parsing","type-mismatch","array","json-data-exception"],"backgroundTag":null,"analyzedSha":"05ea92e90381eb8a8ae06855ea2b74f322bebbec","analyzedAt":"2026-08-14T00:51:35.636Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}