{"record":{"id":"cee5bc78826fca36","repo":"bumptech/glide","slug":"loop-count-must-be-greater-than-0-or-equal-to-gli","errorCode":null,"errorMessage":"Loop count must be greater than 0, or equal to GlideDrawable.LOOP_FOREVER, or equal to GlideDrawable.LOOP_INTRINSIC","messagePattern":"Loop count must be greater than 0, or equal to GlideDrawable\\.LOOP_FOREVER, or equal to GlideDrawable\\.LOOP_INTRINSIC","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java","lineNumber":388,"sourceCode":"    return state;\n  }\n\n  /** Clears any resources for loading frames that are currently held on to by this object. */\n  public void recycle() {\n    isRecycled = true;\n    state.frameLoader.clear();\n  }\n\n  // For testing.\n  boolean isRecycled() {\n    return isRecycled;\n  }\n\n  // Public API.\n  @SuppressWarnings(\"WeakerAccess\")\n  public void setLoopCount(int loopCount) {\n    if (loopCount <= 0 && loopCount != LOOP_FOREVER && loopCount != LOOP_INTRINSIC) {\n      throw new IllegalArgumentException(\n          \"Loop count must be greater than 0, or equal to \"\n              + \"GlideDrawable.LOOP_FOREVER, or equal to GlideDrawable.LOOP_INTRINSIC\");\n    }\n\n    if (loopCount == LOOP_INTRINSIC) {\n      int intrinsicCount = state.frameLoader.getLoopCount();\n      maxLoopCount =\n          (intrinsicCount == TOTAL_ITERATION_COUNT_FOREVER) ? LOOP_FOREVER : intrinsicCount;\n    } else {\n      maxLoopCount = loopCount;\n    }\n  }\n\n  /**\n   * Register callback to listen to GifDrawable animation end event after specific loop count set by\n   * {@link GifDrawable#setLoopCount(int)}.\n   *\n   * <p>Note: This will only be called if the Gif stop because it reaches the loop count. Unregister","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/library/src/main/java/com/bumptech/glide/load/resource/gif/GifDrawable.java#L370-L406","documentation":"IllegalArgumentException thrown by GifDrawable.setLoopCount() when the value is <= 0 and is neither LOOP_FOREVER nor LOOP_INTRINSIC. Loop counts must be a positive integer or one of the two named sentinels; zero and negative values (other than the sentinels) are rejected to avoid an infinite/no-frame playback configuration.","triggerScenarios":"Calling gifDrawable.setLoopCount(0) or setLoopCount(-5). Passing a user-controlled loop count without validation. Computing a loop count that underflows to 0.","commonSituations":"UI controls that let users set loops and send 0 meaning 'none'. Misreading LOOP_INTRINSIC as 0. Storing loop count in an Int that defaults to 0 and passing it through.","solutions":["Use GifDrawable.LOOP_FOREVER or LOOP_INTRINSIC instead of magic numbers.","Validate the value before calling setLoopCount: clamp to >= 1 or use a sentinel.","If 'play once' is desired, call setLoopCount(1)."],"exampleFix":"// before\ngifDrawable.setLoopCount(userLoops); // userLoops may be 0\n// after\nint loops = userLoops <= 0 ? GifDrawable.LOOP_INTRINSIC : userLoops;\ngifDrawable.setLoopCount(loops);","handlingStrategy":"validation","validationCode":"// Clamp user-supplied loop counts before calling setLoopCount.\nint safeLoops;\nif (userLoops == GifDrawable.LOOP_FOREVER || userLoops == GifDrawable.LOOP_INTRINSIC) {\n  safeLoops = userLoops;\n} else {\n  safeLoops = Math.max(1, userLoops);\n}\ngifDrawable.setLoopCount(safeLoops);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the LOOP_FOREVER / LOOP_INTRINSIC sentinels instead of magic numbers.","Clamp external loop-count inputs to >= 1.","Treat 0 as LOOP_INTRINSIC at the call site."],"tags":["gif","drawable","validation","android"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}