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
- Combine both transformations into a single RequestTransformer and register it once
- Delete the duplicate requestTransformer() call
- 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
- Chain transformations inside one transformer instead of registering several
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
- Downloader already set.
- Executor service already set.
- Memory cache already set.
- Listener already set.
- RequestHandler already registered.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/5e9f785266fa943f.
Report an issue: GitHub.