didi/DoKit · error · IllegalArgumentException

Placeholder image resource invalid.

Error message

Placeholder image resource invalid.

What it means

Thrown by RequestCreator.placeholder(int) when the passed resource id is 0. In Android, 0 means 'no resource', so it cannot identify a placeholder drawable; Picasso rejects it rather than silently skipping the placeholder.

Source

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

        }
        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) {
            throw new IllegalStateException("Placeholder image already set.");
        }
        this.placeholderResId = placeholderResId;
        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}.
     * <p>
     * If you are not using a placeholder image but want to clear an existing image (such as when
     * used in an {@link android.widget.Adapter adapter}), pass in {@code null}.
     */
    public RequestCreator placeholder(Drawable placeholderDrawable) {
        if (!setPlaceholder) {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Only call placeholder(resId) when resId != 0; guard the call.
  2. In XML parsing, check typedArray.getResourceId(...) != 0 before using it.
  3. In Kotlin, model optional resource ids as Int? and skip the call when null.

Example fix

// before
int ph = a.getResourceId(R.styleable.MyView_placeholder, 0);
picasso.load(url).placeholder(ph).into(view); // throws when attr unset

// after
int ph = a.getResourceId(R.styleable.MyView_placeholder, 0);
RequestCreator c = picasso.load(url);
if (ph != 0) c.placeholder(ph);
c.into(view);
Defensive patterns

Strategy: validation

Validate before calling

RequestCreator c = picasso.load(url);
if (placeholderResId != 0) c.placeholder(placeholderResId);
c.into(view);

Type guard

static boolean isValidResId(int resId) { return resId != 0; }

Prevention

When it happens

Trigger: Calling placeholder(0), or placeholder(phResId) where the variable is 0 (unset attribute, default parameter value, missing typed-array entry).

Common situations: Reading a custom XML styleable attribute that was not set (typed array returns 0); Java default parameter of 0 flowing through; Kotlin nullable Int mapped to 0 with '?: 0'.

Related errors


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