material-components/material-components-android · error · IllegalArgumentException
invalid shadow size
Error message
invalid shadow size
What it means
ShadowDrawableWrapper.setShadowSize(float, float) throws IllegalArgumentException when either the shadow size or the max shadow size is negative. Sizes are rounded to even pixel values for symmetric shadow rendering; negative dimensions would invert the shadow geometry, so they are rejected immediately.
Source
Thrown at lib/java/com/google/android/material/shadow/ShadowDrawableWrapper.java:127
this.addPaddingForCorners = addPaddingForCorners;
invalidateSelf();
}
@Override
public void setAlpha(int alpha) {
super.setAlpha(alpha);
cornerShadowPaint.setAlpha(alpha);
edgeShadowPaint.setAlpha(alpha);
}
@Override
protected void onBoundsChange(Rect bounds) {
dirty = true;
}
public 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 (!printedShadowClipWarning) {
printedShadowClipWarning = true;
}
}
if (rawShadowSize == shadowSize && rawMaxShadowSize == maxShadowSize) {
return;
}
rawShadowSize = shadowSize;
rawMaxShadowSize = maxShadowSize;
this.shadowSize = Math.round(shadowSize * SHADOW_MULTIPLIER);
this.maxShadowSize = maxShadowSize;
dirty = true;
invalidateSelf();View on GitHub (pinned to ac7e18efee)
Solutions
- Clamp values before the call: setShadowSize(Math.max(0, shadowSize), Math.max(0, maxShadowSize)).
- Fix the arithmetic producing the negative value (check dp * density math and interpolation bounds).
- If animating shadow size, animate within [0, target] and use an interpolator/clamp that cannot overshoot below 0.
Example fix
// before wrapper.setShadowSize(currentElevation - removedElevation, maxShadow); // after wrapper.setShadowSize(Math.max(0f, currentElevation - removedElevation), Math.max(0f, maxShadow));
Defensive patterns
Strategy: validation
Validate before calling
float clamped = Math.max(0f, computedShadowSize); float clampedMax = Math.max(clamped, Math.max(0f, computedMaxShadowSize)); wrapper.setShadowSize(clamped, clampedMax);
Prevention
- Always clamp interpolated elevation to [0, max] with an end-of-animation clamp.
- Unit-test size computations at density extremes (small/xxlarge screens).
When it happens
Trigger: Calling setShadowSize() (directly or via CardView-style elevation helpers) with a negative dp-to-px conversion — e.g. multiplying by a negative density, passing -elevation, or an arithmetic bug that yields < 0.
Common situations: Computing shadow size from a difference like (margin - padding) that can go negative on dense/small screens; interpolating shadow size toward 0 and overshooting slightly below zero; passing raw negative float state values (e.g. scroll offset) as elevation.
Related errors
- Motion easing control point value must be between 0 and 1; i
- Rounded corners without gap are not supported in contiguous
- Keylines being linearly interpolated must have the same item
- Keylines being linearly interpolated must have the same numb
- There must be a keyline marked as focal.
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/982655211a31133d.
Report an issue: GitHub.