didi/DoKit · error · IllegalArgumentException

Set circle needn't set radius.

Error message

Set circle needn't set radius.

What it means

ShadowUtils.Config.setShadowRadius throws if the builder has already been marked circular (isCircle == true). Circular shadows derive their radius from the view's circle dimensions, so an explicit radius is contradictory and rejected. Note the radius is assigned before the check, but the throw still aborts the builder chain.

Source

Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/ShadowUtils.java:78

        private static final int SHADOW_COLOR_DEFAULT = 0x44000000;
        private static final int SHADOW_SIZE          = UtilsBridge.dp2px(8);

        private float   mShadowRadius         = -1;
        private float   mShadowSizeNormal     = -1;
        private float   mShadowSizePressed    = -1;
        private float   mShadowMaxSizeNormal  = -1;
        private float   mShadowMaxSizePressed = -1;
        private int     mShadowColorNormal    = SHADOW_COLOR_DEFAULT;
        private int     mShadowColorPressed   = SHADOW_COLOR_DEFAULT;
        private boolean isCircle              = false;

        public Config() {
        }

        public Config setShadowRadius(float radius) {
            this.mShadowRadius = radius;
            if (isCircle) {
                throw new IllegalArgumentException("Set circle needn't set radius.");
            }
            return this;
        }

        public Config setCircle() {
            isCircle = true;
            if (mShadowRadius != -1) {
                throw new IllegalArgumentException("Set circle needn't set radius.");
            }
            return this;
        }

        public Config setShadowSize(int size) {
            return setShadowSize(size, size);
        }

        public Config setShadowSize(int sizeNormal, int sizePressed) {
            this.mShadowSizeNormal = sizeNormal;

View on GitHub (pinned to 626827cddb)

Solutions

  1. Remove the setShadowRadius call for circular views; the radius comes from the circle itself.
  2. Make the choice exclusive in your code: if (isCircular) cfg.setCircle() else cfg.setShadowRadius(r).
  3. Audit builder chains after converting shapes between circle and rect.

Example fix

// before
new ShadowUtils.Config().setCircle().setShadowRadius(8f).apply(v); // throws

// after
new ShadowUtils.Config().setCircle().apply(v); // radius implicit from circle
Defensive patterns

Strategy: validation

Validate before calling

if (isCircular) cfg.setCircle(); else cfg.setShadowRadius(radius); // never both

Prevention

When it happens

Trigger: Calling config.setCircle() first and then setShadowRadius(10) on the same Config instance; copy-pasted builder chains where both options survive a refactor.

Common situations: Refactoring a rounded-rect shadow into a circular one and forgetting to delete the radius line; conditional builder code that applies radius in one branch and circle in another but both execute.

Related errors


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