didi/DoKit · error · IllegalStateException
Center crop and center inside can not be used together.
Error message
Center crop and center inside can not be used together.
What it means
Thrown by Request.Builder.build() as a defensive invariant check when both centerCrop and centerInside flags are true. The public setters already block setting both (see errors 123/124), so this normally indicates the builder state was manipulated directly (reflection, subclassing, or a modified vendored copy such as this DoKit fork).
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/Request.java:457
/**
* Add a list of custom transformations to be applied to the image.
* <p>
* Custom transformations will always be run after the built-in transformations.
*/
public Builder transform(List<? extends Transformation> transformations) {
if (transformations == null) {
throw new IllegalArgumentException("Transformation list must not be null.");
}
for (int i = 0, size = transformations.size(); i < size; i++) {
transform(transformations.get(i));
}
return this;
}
/** Create the immutable {@link Request} object. */
public Request build() {
if (centerInside && centerCrop) {
throw new IllegalStateException("Center crop and center inside can not be used together.");
}
if (centerCrop && (targetWidth == 0 && targetHeight == 0)) {
throw new IllegalStateException(
"Center crop requires calling resize with positive width and height.");
}
if (centerInside && (targetWidth == 0 && targetHeight == 0)) {
throw new IllegalStateException(
"Center inside requires calling resize with positive width and height.");
}
if (priority == null) {
priority = Priority.NORMAL;
}
return new Request(uri, resourceId, stableKey, transformations, targetWidth, targetHeight,
centerCrop, centerInside, onlyScaleDown, rotationDegrees, rotationPivotX, rotationPivotY,
hasRotationPivot, config, priority);
}
}
}View on GitHub (pinned to 626827cddb)
Solutions
- Use only one of centerCrop()/centerInside(); the two scaling behaviors are mutually exclusive by design.
- If you modified the vendored setters, also decide the combined behavior explicitly instead of relying on build() not to notice.
- Set builder fields only through the public fluent API.
Example fix
// before (reflection / direct field manipulation)
Field f = builder.getClass().getDeclaredField("centerCrop"); // ...both flags forced true
// after
builder.resize(200, 200).centerCrop(); // one strategy, set via the public API Defensive patterns
Strategy: validation
Validate before calling
// Guard in your wrapper before build()
if (usingCrop && usingInside) throw new IllegalArgumentException("pick one strategy"); Prevention
- Never set builder flags via reflection or field access.
- If you fork Picasso (as DoKit did), keep setter guards and the build() invariant consistent.
When it happens
Trigger: Setting both flags true through reflection or a custom Builder subclass, or a locally modified copy of Picasso where a setter guard was removed; then calling build().
Common situations: Forking/vendoring Picasso (as DoKit does) and relaxing one of the setter guards without realizing build() re-checks the invariant; bytecode manipulation or test code that sets fields directly.
Related errors
- Downloader already set.
- Executor service must not be null.
- Executor service already set.
- Memory cache must not be null.
- Memory cache already set.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/952b6278f53cb479.
Report an issue: GitHub.