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
- Use exactly one of placeholder(Drawable) or noPlaceholder() per request.
- Push the placeholder decision into one helper parameter (e.g., placeholderResId, 0 = none).
- 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
- Model the placeholder as one optional value (resId XOR drawable XOR none).
- Never call noPlaceholder() after any placeholder was set on the same creator.
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
- Placeholder resource already set.
- Already explicitly declared as no placeholder.
- Center crop can not be used after calling centerInside
- Center inside can not be used after calling centerCrop
- Priority already set.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/abd552f9e232e11e.
Report an issue: GitHub.