Blankj/AndroidUtilCode · error · IllegalArgumentException

invalid shadow size

Error message

invalid shadow size

What it means

ShadowUtils.setShadowSize validates that both shadowSize and maxShadowSize are non-negative, throwing IllegalArgumentException otherwise. Shadow sizes represent pixel dimensions of the shadow drawable, which cannot be negative. The guard rejects invalid input before it propagates into the paint/layout math (toEven rounding, shadow multiplier scaling).

Source

Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/ShadowUtils.java:264

            mAddPaddingForCorners = addPaddingForCorners;
            invalidateSelf();
        }

        @Override
        public void setAlpha(int alpha) {
            super.setAlpha(alpha);
            mCornerShadowPaint.setAlpha(alpha);
            mEdgeShadowPaint.setAlpha(alpha);
        }

        @Override
        protected void onBoundsChange(Rect bounds) {
            mDirty = true;
        }

        void setShadowSize(float shadowSize, float maxShadowSize) {
            if (shadowSize < 0 || maxShadowSize < 0) {
                throw new IllegalArgumentException("invalid shadow size");
            }
            shadowSize = toEven(shadowSize);
            maxShadowSize = toEven(maxShadowSize);
            if (shadowSize > maxShadowSize) {
                shadowSize = maxShadowSize;
            }
            if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) {
                return;
            }
            mRawShadowSize = shadowSize;
            mRawMaxShadowSize = maxShadowSize;
            mShadowSize = Math.round(shadowSize * mShadowMultiplier);
            mMaxShadowSize = maxShadowSize;
            mDirty = true;
            invalidateSelf();
        }

        @Override

View on GitHub (pinned to 7b4caf9e54)

Solutions

  1. Clamp or validate the size to >= 0 before calling setShadowSize.
  2. Replace negative sentinels (-1 meaning unset) with 0 or an explicit 'no shadow' branch.
  3. Assert in debug builds that computed sizes are non-negative to catch the source early.
  4. If the value comes from a dimension resource, verify resValues are positive at build time.

Example fix

// before
float size = requestedSize; // could be -1
shadowUtils.setShadowSize(size, maxSize);

// after
float size = Math.max(0f, requestedSize);
shadowUtils.setShadowSize(size, Math.max(size, maxSize));
Defensive patterns

Strategy: validation

Validate before calling

if (shadowSize < 0 || maxShadowSize < 0) {
  throw new IllegalArgumentException("shadow sizes must be >= 0");
}
shadowUtils.setShadowSize(shadowSize, maxShadowSize);

Try / catch

try {
  shadowUtils.setShadowSize(size, max);
} catch (IllegalArgumentException e) {
  size = Math.max(0f, size);
  max  = Math.max(0f, max);
  shadowUtils.setShadowSize(size, max);
}

Prevention

When it happens

Trigger: Calling setShadowSize with a negative float, or constructing a ShadowUtils drawable and invoking its internal setShadowSize(-1, x) / setShadowSize(x, -1). Also reachable via Config.setShadowSize if it forwards negative sizes downstream.

Common situations: Passing a resource dimension that resolved to a negative sentinel (-1 default); computing size from a delta that underflows to negative; porting code that used -1 as an 'unset' marker; reading size from a malformed config file.

Related errors


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/a7fa17cea82eea52. Report an issue: GitHub.