{"record":{"id":"0335b658231b72d9","repo":"airbnb/lottie-android","slug":"expected-begin-array-but-was-at-path","errorCode":null,"errorMessage":"Expected BEGIN_ARRAY but was {} at path {}","messagePattern":"Expected BEGIN_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":121,"sourceCode":"    }\n    this.source = source;\n    // Don't use source.getBuffer(). Because android studio use old version okio instead of your own okio.\n    this.buffer = source.buffer();\n    pushScope(JsonScope.EMPTY_DOCUMENT);\n  }\n\n\n  @Override public void beginArray() throws IOException {\n    int p = peeked;\n    if (p == PEEKED_NONE) {\n      p = doPeek();\n    }\n    if (p == PEEKED_BEGIN_ARRAY) {\n      pushScope(JsonScope.EMPTY_ARRAY);\n      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  }","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/airbnb/lottie-android/blob/05ea92e90381eb8a8ae06855ea2b74f322bebbec/lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java#L103-L139","documentation":"JsonUtf8Reader.beginArray() peeks the next token and expects PEEKED_BEGIN_ARRAY ('['). If the actual token is anything else (object, string, number, etc.), it throws JsonDataException with the actual token and current path. This enforces structural expectations during Lottie JSON parsing — properties that must be arrays (keyframe arrays, point arrays, etc.) must actually be arrays.","triggerScenarios":"The parser calls beginArray() expecting an array but encounters a different JSON structure — e.g., a property that should be an array of keyframes is instead a single object, number, or string. This typically means the Lottie JSON deviates from the expected schema at that location.","commonSituations":"Malformed or non-standard Lottie JSON where an array-typed field is encoded as a different type; animation exported by an incompatible tool version; hand-edited JSON where array brackets were accidentally removed.","solutions":["Use the path in the exception message to find the exact field, then verify its JSON type matches what the Lottie schema expects (array in this case).","Validate the animation with LottieFiles validator.","Re-export the animation from a supported version of After Effects + Bodymovin/LottieFiles plugin."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"LottieTask<LottieComposition> task = LottieCompositionFactory.fromAsset(context, name);\ntask.addListener(result -> { /* success */ })\n     .addFailureListener(e -> {\n         if (e instanceof JsonDataException) {\n             // structural type mismatch — JSON is malformed\n         }\n     });","preventionTips":["Validate Lottie JSON structure with LottieFiles validator before bundling.","Use async LottieCompositionFactory APIs for graceful error handling.","Re-export from supported tool versions."],"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"}