{"record":{"id":"8f2b92d04e2920cf","repo":"airbnb/lottie-android","slug":"source-null","errorCode":null,"errorMessage":"source == null","messagePattern":"source == null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java","lineNumber":102,"sourceCode":"   */\n  private long peekedLong;\n\n  /**\n   * The number of characters in a peeked number literal.\n   */\n  private int peekedNumberLength;\n\n  /**\n   * A peeked string that should be parsed on the next double, long or string.\n   * This is populated before a numeric value is parsed and used if that parsing\n   * fails.\n   */\n  private @Nullable\n  String peekedString;\n\n  JsonUtf8Reader(BufferedSource source) {\n    if (source == null) {\n      throw new NullPointerException(\"source == null\");\n    }\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 {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/airbnb/lottie-android/blob/05ea92e90381eb8a8ae06855ea2b74f322bebbec/lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java#L84-L120","documentation":"The JsonUtf8Reader constructor takes a BufferedSource (Okio) and immediately checks for null. If null, it throws NullPointerException. This is a programmer-error guard — the reader cannot function without a data source. This exception should never reach end users; it indicates a bug in calling code.","triggerScenarios":"Constructing a JsonUtf8Reader (typically via JsonReader.of() or the Lottie parser internals) with a null BufferedSource argument. This happens when the input stream, file, or asset that should provide JSON is null before being wrapped.","commonSituations":"Loading a Lottie animation from an asset/resource that doesn't exist (getAssets().open() returns null or is wrapped incorrectly); passing a null InputStream to the parser; broken asset path in the app; proguard/R8 stripping causing a null source to be passed unexpectedly.","solutions":["Check that the animation file/asset exists and the path is correct before attempting to load it.","Null-check the InputStream/BufferedSource before passing it to LottieAnimationView.setAnimation() or the parser.","Verify asset filenames match exactly (case-sensitive on Android) and the file is in the correct assets/ directory."],"exampleFix":"// before\nInputStream stream = getAssets().open(name); // may throw or return null\nLottieCompositionFactory.fromInputStream(stream); // NPE if stream is null\n\n// after\nInputStream stream = getAssets().open(name);\nif (stream == null) {\n    Log.e(TAG, \"Animation asset not found: \" + name);\n    return;\n}\nLottieCompositionFactory.fromInputStream(stream);","handlingStrategy":"validation","validationCode":"// Null-check the source before loading\nInputStream stream = null;\ntry {\n    stream = context.getAssets().open(name);\n} catch (IOException e) {\n    // asset missing\n}\nif (stream == null) {\n    // do not pass to Lottie\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always null-check InputStream/BufferedSource before passing to Lottie APIs.","Verify asset paths are correct (case-sensitive on Android).","Handle IOException from AssetManager.open() gracefully."],"tags":["lottie","json-parsing","null-pointer","programmer-error","input-source"],"backgroundTag":null,"analyzedSha":"05ea92e90381eb8a8ae06855ea2b74f322bebbec","analyzedAt":"2026-08-14T00:51:35.636Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}