{"record":{"id":"dd04a0286cd87ccf","repo":"airbnb/lottie-android","slug":"end-of-input","errorCode":null,"errorMessage":"End of input","messagePattern":"End of input","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java","lineNumber":943,"sourceCode":"            skipToEndOfLine();\n            p = 0;\n            continue;\n\n          default:\n            return c;\n        }\n      } else if (c == '#') {\n        // Skip a # hash end-of-line comment. The JSON RFC doesn't specify this behaviour, but it's\n        // required to parse existing documents.\n        checkLenient();\n        skipToEndOfLine();\n        p = 0;\n      } else {\n        return c;\n      }\n    }\n    if (throwOnEof) {\n      throw new EOFException(\"End of input\");\n    } else {\n      return -1;\n    }\n  }\n\n  private void checkLenient() throws IOException {\n    if (!lenient) {\n      throw syntaxError(\"Use JsonReader.setLenient(true) to accept malformed JSON\");\n    }\n  }\n\n  /**\n   * Advances the position until after the next newline character. If the line\n   * is terminated by \"\\r\\n\", the '\\n' must be consumed as whitespace by the\n   * caller.\n   */\n  private void skipToEndOfLine() throws IOException {\n    long index = source.indexOfElement(LINEFEED_OR_CARRIAGE_RETURN);","sourceCodeStart":925,"sourceCodeEnd":961,"githubUrl":"https://github.com/airbnb/lottie-android/blob/05ea92e90381eb8a8ae06855ea2b74f322bebbec/lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonUtf8Reader.java#L925-L961","documentation":"Thrown by nextNonWhitespace() (an internal method called by doPeek()) when the input source is exhausted while looking for the next meaningful character and throwOnEof is true. This is the fundamental 'unexpected end of JSON document' error — the parser needed more input to determine the next token type but none was available.","triggerScenarios":"The reader's doPeek() calls nextNonWhitespace() to find the next non-whitespace character, but source.request() returns false (no more data) and throwOnEof is true. This occurs at the very start of parsing (empty input), or mid-document when the stream ends after whitespace (e.g., trailing whitespace at EOF after a complete value is fine, but EOF while expecting another token triggers this). The throw is at line 943.","commonSituations":"An empty or whitespace-only JSON input passed to Lottie. A truncated Lottie animation file. A network stream that closed prematurely. A file that was partially written. An input stream that threw during reading. This is often the first error seen when the input is fundamentally incomplete.","solutions":["Verify the JSON input is non-empty and complete before passing to Lottie — check that it starts with '{' or '[' and ends with '}' or ']'","Ensure the full file or stream is available: for assets, check the file exists and has content; for network, verify the response body","If reading from a stream, buffer the entire input into a String or BufferedSource first, then validate before parsing","Catch EOFException (or IOException) during composition loading and provide a fallback"],"exampleFix":"// before: passing an empty or truncated stream\n// LottieCompositionFactory.fromJsonData(\"\", cacheKey); // empty string\n\n// after: validate input before loading\nif (jsonData == null || jsonData.trim().isEmpty()) {\n  Log.e(TAG, \"Animation JSON is empty\");\n  showFallback();\n  return;\n}\nLottieCompositionFactory.fromJsonData(jsonData, cacheKey);","handlingStrategy":"validation","validationCode":"// Validate input is non-empty and looks like JSON before loading\nboolean isValidLottieJson(String json) {\n  if (json == null || json.trim().isEmpty()) return false;\n  String trimmed = json.trim();\n  return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n}\n\n// Usage before loading:\nif (!isValidLottieJson(jsonData)) {\n  Log.e(TAG, \"Invalid or empty Lottie JSON input\");\n  showFallback();\n  return;\n}\nLottieCompositionFactory.fromJsonData(jsonData, cacheKey);","typeGuard":null,"tryCatchPattern":"try {\n  LottieCompositionFactory.fromJsonData(jsonData, cacheKey);\n} catch (EOFException e) {\n  Log.w(TAG, \"Unexpected end of Lottie JSON input: \" + e.getMessage());\n  showFallbackAnimation();\n} catch (IOException e) {\n  Log.w(TAG, \"I/O error reading Lottie JSON: \" + e.getMessage());\n  showFallbackAnimation();\n}","preventionTips":["Always check that the JSON input is non-null and non-empty before loading","For network sources, buffer the entire response before parsing","Verify file assets exist and have non-zero size before opening"],"tags":["json-parsing","moshi","lottie","eof","truncated-input"],"backgroundTag":null,"analyzedSha":"05ea92e90381eb8a8ae06855ea2b74f322bebbec","analyzedAt":"2026-08-14T00:51:35.636Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}