{"record":{"id":"144c1b8beb18ca55","repo":"bumptech/glide","slug":"cannot-apply-transformation-on-width-outwidth-o","errorCode":null,"errorMessage":"Cannot apply transformation on width: {outWidth} or height: {outHeight} less than or equal to zero and not Target.SIZE_ORIGINAL","messagePattern":"Cannot apply transformation on width: (.+?) or height: (.+?) less than or equal to zero and not Target\\.SIZE_ORIGINAL","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java","lineNumber":72,"sourceCode":" * Class#getName()} to avoid proguard obfuscation) is an easy way to implement {@link\n * #updateDiskCacheKey(java.security.MessageDigest)}} correctly. If additional arguments are\n * required they can be passed in to the constructor of the {@code Transformation} and then used to\n * update the {@link java.security.MessageDigest} passed in to {@link\n * #updateDiskCacheKey(MessageDigest)}. If arguments are primitive types, they can typically easily\n * be serialized using {@link java.nio.ByteBuffer}. {@link String} types can be serialized with\n * {@link String#getBytes(Charset)} using the constant {@link #CHARSET}.\n *\n * <p>As with all {@link Transformation}s, all subclasses <em>must</em> implement {@link\n * #equals(Object)} and {@link #hashCode()} for memory caching to work correctly.\n */\npublic abstract class BitmapTransformation implements Transformation<Bitmap> {\n\n  @NonNull\n  @Override\n  public final Resource<Bitmap> transform(\n      @NonNull Context context, @NonNull Resource<Bitmap> resource, int outWidth, int outHeight) {\n    if (!Util.isValidDimensions(outWidth, outHeight)) {\n      throw new IllegalArgumentException(\n          \"Cannot apply transformation on width: \"\n              + outWidth\n              + \" or height: \"\n              + outHeight\n              + \" less than or equal to zero and not Target.SIZE_ORIGINAL\");\n    }\n    BitmapPool bitmapPool = Glide.get(context).getBitmapPool();\n    Bitmap toTransform = resource.get();\n    int targetWidth = outWidth == Target.SIZE_ORIGINAL ? toTransform.getWidth() : outWidth;\n    int targetHeight = outHeight == Target.SIZE_ORIGINAL ? toTransform.getHeight() : outHeight;\n    Bitmap transformed = transform(bitmapPool, toTransform, targetWidth, targetHeight);\n\n    final Resource<Bitmap> result;\n    if (toTransform.equals(transformed)) {\n      result = resource;\n    } else {\n      result = BitmapResource.obtain(transformed, bitmapPool);\n    }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/BitmapTransformation.java#L54-L90","documentation":"Thrown by BitmapTransformation.transform() when Util.isValidDimensions(outWidth, outHeight) returns false. Glide requires target dimensions to be either positive integers or Target.SIZE_ORIGINAL (Integer.MIN_VALUE). Any other non-positive value is rejected before the transformation runs because it cannot produce a valid Bitmap.","triggerScenarios":"Calling .override(width, height) with 0 or a negative value other than Target.SIZE_ORIGINAL on a request that applies a BitmapTransformation (CenterCrop, RoundedCorners, etc.). Also triggered by a custom Transformation that forwards invalid outWidth/outHeight, or by computed dimensions (e.g. view measured width/height of 0 passed through override().","commonSituations":"Loading into a View that has not been laid out yet (getWidth()==0) and feeding those dimensions via .override(). Passing -1 as a sentinel instead of Target.SIZE_ORIGINAL. Miscalculating dimensions in a custom target's onResourceReady before calling run() or into().","solutions":["Use Target.SIZE_ORIGINAL instead of -1 or 0 when you want the original size.","Guard the call site: only call .override(w, h) when w > 0 && h > 0, otherwise omit override() to let Glide use the target dimensions.","Defer the load until after the target View has been measured (e.g. in onPreDraw listener or after layout).","If you compute dimensions, validate them and fall back to Target.SIZE_ORIGINAL when invalid."],"exampleFix":"// before\nGlide.with(view).load(url).override(view.getWidth(), view.getHeight()).into(view);\n// after (guard against 0)\nint w = view.getWidth();\nint h = view.getHeight();\nRequestBuilder<Drawable> req = Glide.with(view).load(url);\nif (w > 0 && h > 0) {\n  req = req.override(w, h);\n}\nreq.into(view);","handlingStrategy":"validation","validationCode":"// Validate dimensions before calling override() or a transformation.\nboolean isValidGlideDimension(int w, int h) {\n  return (w > 0 && h > 0)\n      || w == Target.SIZE_ORIGINAL\n      || h == Target.SIZE_ORIGINAL;\n}\n// Usage:\nRequestBuilder<Drawable> req = Glide.with(view).load(url);\nif (isValidGlideDimension(w, h)) req = req.override(w, h);\nreq.into(view);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always treat Target.SIZE_ORIGINAL as the only valid non-positive dimension sentinel.","Guard override() calls in onResourceReady / target callbacks where dimensions may be 0.","Defer image loads until the host View has been measured."],"tags":["bitmap","transformation","dimensions","validation","android"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}