didi/DoKit · error · IllegalStateException

Transformer already set.

Error message

Transformer already set.

What it means

DokitPicasso.Builder.requestTransformer() throws IllegalStateException when a RequestTransformer has already been set. The transformer slot is single-assignment, mirroring upstream Picasso where chaining two transformers is a configuration error.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java:782

      if (this.listener != null) {
        throw new IllegalStateException("Listener already set.");
      }
      this.listener = listener;
      return this;
    }

    /**
     * Specify a transformer for all incoming requests.
     * <p>
     * <b>NOTE:</b> This is a beta feature. The API is subject to change in a backwards incompatible
     * way at any time.
     */
    public Builder requestTransformer(RequestTransformer transformer) {
      if (transformer == null) {
        throw new IllegalArgumentException("Transformer must not be null.");
      }
      if (this.transformer != null) {
        throw new IllegalStateException("Transformer already set.");
      }
      this.transformer = transformer;
      return this;
    }

    /** Register a {@link RequestHandler}. */
    public Builder addRequestHandler(RequestHandler requestHandler) {
      if (requestHandler == null) {
        throw new IllegalArgumentException("RequestHandler must not be null.");
      }
      if (requestHandlers == null) {
        requestHandlers = new ArrayList<RequestHandler>();
      }
      if (requestHandlers.contains(requestHandler)) {
        throw new IllegalStateException("RequestHandler already registered.");
      }
      requestHandlers.add(requestHandler);
      return this;

View on GitHub (pinned to 626827cddb)

Solutions

  1. Combine both transformations into a single RequestTransformer and register it once
  2. Delete the duplicate requestTransformer() call
  3. Reconfigure from a new Builder if the pipeline must change wholesale

Example fix

// before
builder.requestTransformer(new AuthTransformer());
builder.requestTransformer(new CdnTransformer()); // IllegalStateException

// after
class ChainedTransformer implements DokitPicasso.RequestTransformer {
  ...apply auth then cdn...
}
builder.requestTransformer(new ChainedTransformer());
Defensive patterns

Strategy: validation

Validate before calling

class Chained implements DokitPicasso.RequestTransformer { public Request transformRequest(Request r) { return second.transformRequest(first.transformRequest(r)); } }
builder.requestTransformer(new Chained()); // single call

Try / catch

try { builder.requestTransformer(t); } catch (IllegalStateException e) { if (!e.getMessage().contains("Transformer already set")) throw e; }

Prevention

When it happens

Trigger: Calling builder.requestTransformer(...) twice on the same Builder, e.g. one transformer added by shared code and another by feature-specific code.

Common situations: Merging init paths after refactoring; a common module and an app module each installing their own URL-rewriting transformer.

Related errors


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