{"record":{"id":"61964a3d6038d584","repo":"bumptech/glide","slug":"already-released","errorCode":null,"errorMessage":"Already released","messagePattern":"Already released","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/bumptech/glide/util/pool/StateVerifier.java","lineNumber":40,"sourceCode":"  /**\n   * Throws an exception if we believe our object is recycled and inactive (i.e. is currently in an\n   * object pool).\n   */\n  public abstract void throwIfRecycled();\n\n  /** Sets whether or not our object is recycled. */\n  abstract void setRecycled(boolean isRecycled);\n\n  private static class DefaultStateVerifier extends StateVerifier {\n    private volatile boolean isReleased;\n\n    @Synthetic\n    DefaultStateVerifier() {}\n\n    @Override\n    public void throwIfRecycled() {\n      if (isReleased) {\n        throw new IllegalStateException(\"Already released\");\n      }\n    }\n\n    @Override\n    public void setRecycled(boolean isRecycled) {\n      this.isReleased = isRecycled;\n    }\n  }\n\n  private static class DebugStateVerifier extends StateVerifier {\n    // Keeps track of the stack trace where our state was set to recycled.\n    private volatile RuntimeException recycledAtStackTraceException;\n\n    @Synthetic\n    DebugStateVerifier() {}\n\n    @Override\n    public void throwIfRecycled() {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/library/src/main/java/com/bumptech/glide/util/pool/StateVerifier.java#L22-L58","documentation":"Thrown by StateVerifier.DefaultStateVerifier.throwIfRecycled when isReleased is true. StateVerifier guards pooled/recycled objects (notably SingleRequest and other request objects in Glide's pool) so they are not reused after release/recycle. Reuse of a recycled object would produce corrupted state and stale callbacks, so the guard fails fast.","triggerScenarios":"Holding a reference to a Glide Request/Target after it has been cleared/recycled and then calling a method on it (begin, clear, pause, etc.); Double-clearing a request; using a ViewTarget after Glide cleared it and the underlying request was returned to the pool.","commonSituations":"Caching a Request or Target in a field and reusing it across config changes; RecyclerView ViewHolders that retain stale Targets after onViewRecycled; calling request.begin() after RequestManager.clear recycled it; library bugs that re-emit callbacks on a recycled request.","solutions":["Do not retain references to Glide Request objects; let RequestManager/into(ImageView) own the lifecycle","For custom Targets, null out the reference after onLoadCleared and stop using it","In RecyclerView, clear targets in onViewRecycled and create fresh loads on rebind","If you suspect a Glide bug, enable DebugStateVerifier (StateVerifier.DEBUG=true via reflection in a debug build) to capture the stack trace of the original release"],"exampleFix":"// before\nclass MyHolder(itemView: View) {\n  var target: Target<Drawable>? = null\n  fun bind(url: String) {\n    target = Glide.with(itemView).load(url).into(imageView)\n  }\n  fun onRecycled() {\n    target // still held; later use throws 'Already released'\n  }\n}\n\n// after\nclass MyHolder(itemView: View) {\n  fun bind(url: String) {\n    Glide.with(itemView).load(url).into(imageView) // Glide tracks the request\n  }\n  fun onRecycled() {\n    Glide.with(itemView).clear(imageView)\n  }\n}","handlingStrategy":"validation","validationCode":"// Don't hold Request references; let Glide own them. For custom Targets:\n@Volatile var cleared = false\noverride fun onLoadCleared(placeholder: Drawable?) {\n  cleared = true\n  // null out references, stop using this target\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not retain Glide Request/Target references after clear/onLoadCleared","Use the high-level into(ImageView) API so Glide owns request pooling","Clear targets in RecyclerView.onViewRecycled; create fresh loads on rebind","In debug builds, enable StateVerifier.DEBUG via reflection to capture the original release stack"],"tags":["android","glide","object-pool","lifecycle","recycling","state-machine"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}