{"record":{"id":"acb3a0652994a251","repo":"bumptech/glide","slug":"cannot-call-evictonworkthread-on-thread","errorCode":null,"errorMessage":"Cannot call evictOnWorkThread on thread: {}","messagePattern":"Cannot call evictOnWorkThread on thread: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"integration/sqljournaldiskcache/src/main/java/com/bumptech/glide/integration/sqljournaldiskcache/EvictionManager.java","lineNumber":100,"sourceCode":"   * cache size.\n   */\n  void maybeScheduleEviction() {\n    maybeScheduleEviction(getMaximumSizeBytes());\n  }\n\n  private void maybeScheduleEviction(long maximumSizeBytes) {\n    if (isEvictionRequired(maximumSizeBytes)) {\n      evictionHandler.obtainMessage(MessageIds.EVICT).sendToTarget();\n    }\n  }\n\n  private boolean isEvictionRequired(long maximumSizeBytes) {\n    return journal.getCurrentSizeBytes() > evictionSlopBytes + maximumSizeBytes;\n  }\n\n  private void evictOnWorkThread() {\n    if (!Looper.myLooper().equals(workLooper)) {\n      throw new IllegalStateException(\n          \"Cannot call evictOnWorkThread on thread: \" + Thread.currentThread().getName());\n    }\n    long maximumSizeBytes = getMaximumSizeBytes();\n    long staleDateMs = clock.currentTimeMillis() - staleEvictionThresholdMs;\n    List<String> staleEntriesKeys = journal.getStaleEntries(staleDateMs);\n    // Writes may queue up a number of eviction messages. After the first one runs, eviction may no\n    // longer be necessary, so we simply ignore the message.\n    if (!isEvictionRequired(maximumSizeBytes) && staleEntriesKeys.isEmpty()) {\n      if (LOG_VERBOSE) {\n        Log.v(TAG, \"Ignoring eviction, not needed\");\n      }\n      return;\n    }\n    if (LOG_DEBUG) {\n      Log.d(TAG, \"Starting eviction on work thread\");\n    }\n\n    int successfullyDeletedCount = 0;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/integration/sqljournaldiskcache/src/main/java/com/bumptech/glide/integration/sqljournaldiskcache/EvictionManager.java#L82-L118","documentation":"Thrown by the SQL journal disk cache's EvictionManager.evictOnWorkThread() when invoked from a thread whose Looper is not the dedicated work Looper. Eviction touches the SQLite journal and must be serialized on the single work thread to avoid corruption.","triggerScenarios":"evictOnWorkThread() runs and Looper.myLooper() does not equal workLooper. Normally eviction is posted as a Message to the work-thread Handler; this fires only if eviction is invoked directly from the wrong thread.","commonSituations":"Calling an internal/eviction method directly instead of through the public API; a misconfigured Handler in a test; reflection invoking evictOnWorkThread off-thread. In normal library use this should not occur because eviction is always posted to the work Handler.","solutions":["Use the public disk-cache API; never call EvictionManager methods directly.","If testing, run assertions on the work thread (e.g. via the work-thread Handler.post) or use the provided test helpers.","Ensure you did not obtain or share the EvictionManager across components that post to a different Looper.","Report a bug if the error appears during ordinary library usage, since eviction should always be internally scheduled."],"exampleFix":"// before (wrong thread)\nevictionManager.evictOnWorkThread() // called from main thread\n\n// after (let the library schedule it)\ndiskCache.put(key, data) // internally posts eviction to the work thread","handlingStrategy":"validation","validationCode":"// Only schedule eviction through the public API on the work thread.\nif (Looper.myLooper() == workLooper) {\n  evictionManager.evictOnWorkThread()\n} else {\n  error(\"Eviction must run on the work thread\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call EvictionManager internals directly; use the disk-cache public API.","In tests, post work to the work-thread Handler.","Keep a single EvictionManager per cache directory."],"tags":["sqljournaldiskcache","integration","threading","looper","runtime"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}