didi/DoKit · error · IllegalStateException

Placeholder image already set.

Error message

Placeholder image already set.

What it means

Thrown by RequestCreator.noPlaceholder() when a placeholder Drawable was already set via placeholder(Drawable). It is the Drawable variant of the resource guard: once any placeholder exists, opting out of placeholders on the same creator is a contradiction and fails fast.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/RequestCreator.java:97

    RequestCreator() {
        this.picasso = null;
        this.data = new Request.Builder(null, 0, null);
    }

    /**
     * Explicitly opt-out to having a placeholder set when calling {@code into}.
     * <p>
     * By default, Picasso will either set a supplied placeholder or clear the target
     * {@link ImageView} in order to ensure behavior in situations where views are recycled. This
     * method will prevent that behavior and retain any already set image.
     */
    public RequestCreator noPlaceholder() {
        if (placeholderResId != 0) {
            throw new IllegalStateException("Placeholder resource already set.");
        }
        if (placeholderDrawable != null) {
            throw new IllegalStateException("Placeholder image already set.");
        }
        setPlaceholder = false;
        return this;
    }

    /**
     * A placeholder drawable to be used while the image is being loaded. If the requested image is
     * not immediately available in the memory cache then this resource will be set on the target
     * {@link ImageView}.
     */
    public RequestCreator placeholder(int placeholderResId) {
        if (!setPlaceholder) {
            throw new IllegalStateException("Already explicitly declared as no placeholder.");
        }
        if (placeholderResId == 0) {
            throw new IllegalArgumentException("Placeholder image resource invalid.");
        }
        if (placeholderDrawable != null) {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Use exactly one of placeholder(Drawable) or noPlaceholder() per request.
  2. Push the placeholder decision into one helper parameter (e.g., placeholderResId, 0 = none).
  3. Grep request chains for both '.placeholder(' and '.noPlaceholder()' appearing together.

Example fix

// before
public void show(String url, Drawable ph) {
  RequestCreator c = picasso.load(url).placeholder(ph);
  if (ph == null) c.noPlaceholder(); // throws when ph != null path already set it
}

// after
public void show(String url, Drawable ph) {
  RequestCreator c = picasso.load(url);
  if (ph != null) c.placeholder(ph); else c.noPlaceholder();
}
Defensive patterns

Strategy: validation

Validate before calling

RequestCreator c = picasso.load(url);
if (placeholderDrawable != null) c.placeholder(placeholderDrawable); else c.noPlaceholder();

Prevention

When it happens

Trigger: Chaining .placeholder(drawable).noPlaceholder() on the same RequestCreator.

Common situations: Default placeholder drawable applied in shared loading code, then noPlaceholder() added at a specific call site; refactoring that merges a placeholder branch with a no-placeholder branch.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/abd552f9e232e11e. Report an issue: GitHub.