bumptech/glide · error · IllegalArgumentException

You must call #load() before calling #into()

Error message

You must call #load() before calling #into()

What it means

Glide's into() method on RequestBuilder checks the isModelSet flag, which is only set to true after a call to load() or one of its variants (load(String), load(Uri), load(File), etc.). Calling into() without first specifying what to load leaves the request with no data source, so Glide throws an IllegalArgumentException. The flag ensures the request pipeline always has a model to work with.

Source

Thrown at library/src/main/java/com/bumptech/glide/RequestBuilder.java:849

    return into(target, /* targetListener= */ null, Executors.mainThreadExecutorFront());
  }

  @NonNull
  public <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      Executor callbackExecutor) {
    return into(target, targetListener, /* options= */ this, callbackExecutor);
  }

  private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      // If the request is completed, beginning again will ensure the result is re-delivered,
      // triggering RequestListeners and Targets. If the request is failed, beginning again will
      // restart the request, giving it another chance to complete. If the request is already
      // running, we can let it continue running without interruption.
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // Use the previous request rather than the new one to allow for optimizations like skipping
        // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
        // that are done in the individual Request.
        previous.begin();
      }
      return target;

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Always chain load() before into(): Glide.with(context).load(url).into(target)
  2. If you store a RequestBuilder, call load() on the instance immediately before into() each time
  3. Use the full fluent chain in one expression to avoid missing the load step

Example fix

// before
Glide.with(this).into(imageView);
// after
Glide.with(this).load(imageUrl).into(imageView);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure load() is always called before into() by using the fluent chain pattern
Glide.with(context)
    .load(url)       // sets isModelSet = true
    .into(imageView); // safe to call now

Prevention

When it happens

Trigger: Calling Glide.with(view).into(target) with no load() call in between. Reusing a RequestBuilder that was cloned before load() was called. Calling into() after clear() without re-invoking load().

Common situations: Chaining Glide.with(fragment).into(imageView) and forgetting the load(url) step. Extracting a RequestBuilder as a field and calling into() on it from multiple places where the load state is ambiguous. Refactoring that accidentally drops the load() call.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/1f4df57ecebed1b2. Report an issue: GitHub.