didi/DoKit · error · IllegalStateException

Tag already set.

Error message

Tag already set.

What it means

Thrown by RequestCreator.tag(Object) when a tag was already assigned on the same builder. A request belongs to exactly one tag group; a second tag() call would make cancel/pause/resume semantics ambiguous, so Picasso throws IllegalStateException.

Source

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

     * You can either use simple {@link String} tags or objects that naturally
     * define the scope of your requests within your app such as a
     * {@link android.content.Context}, an {@link android.app.Activity}, or a
     * {@link android.app.Fragment}.
     *
     * <strong>WARNING:</strong>: Picasso will keep a reference to the tag for
     * as long as this tag is paused and/or has active requests. Look out for
     * potential leaks.
     *
     * @see DokitPicasso#cancelTag(Object)
     * @see DokitPicasso#pauseTag(Object)
     * @see DokitPicasso#resumeTag(Object)
     */
    public RequestCreator tag(Object tag) {
        if (tag == null) {
            throw new IllegalArgumentException("Tag invalid.");
        }
        if (this.tag != null) {
            throw new IllegalStateException("Tag already set.");
        }
        this.tag = tag;
        return this;
    }

    /**
     * Attempt to resize the image to fit exactly into the target {@link ImageView}'s bounds. This
     * will result in delayed execution of the request until the {@link ImageView} has been laid out.
     * <p>
     * <em>Note:</em> This method works only when your target is an {@link ImageView}.
     */
    public RequestCreator fit() {
        deferred = true;
        return this;
    }

    /**
     * Internal use only. Used by {@link DeferredRequestCreator}.

View on GitHub (pinned to 626827cddb)

Solutions

  1. Keep exactly one tag() call per chain — decide the owner of the tag (helper or call site)
  2. Make the helper's tag conditional or pass the tag into the helper as a parameter
  3. Start a fresh request chain instead of retagging an existing one

Example fix

// before
RequestCreator rc = picasso.load(url).tag("screen");
rc.tag("feed-item-42"); // throws "Tag already set."

// after
RequestCreator rc = picasso.load(url).tag("feed-item-42");
Defensive patterns

Strategy: validation

Validate before calling

// Assign the tag exactly once, from one owner
Object tag = (customTag != null) ? customTag : DEFAULT_TAG;
rc.tag(tag);

Prevention

When it happens

Trigger: Calling .tag(tagA).tag(tagB) on the same RequestCreator, e.g. shared code sets a default tag and the call site adds another.

Common situations: Base activity/fragment helper classes that tag every request with the screen, combined with call sites adding their own tag; retry wrappers that re-apply a tag to a reused builder.

Related errors


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