{"record":{"id":"3e66047fa9856565","repo":"material-components/material-components-android","slug":"cradleverticaloffset-must-be-positive","errorCode":null,"errorMessage":"cradleVerticalOffset must be positive.","messagePattern":"cradleVerticalOffset must be positive\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/bottomappbar/BottomAppBarTopEdgeTreatment.java","lineNumber":233,"sourceCode":"  }\n\n  /**\n   * Returns vertical offset, in pixels, of the {@link FloatingActionButton} being cradled. An\n   * offset of 0 indicates the vertical center of the {@link FloatingActionButton} is positioned on\n   * the top edge.\n   */\n  float getCradleVerticalOffset() {\n    return cradleVerticalOffset;\n  }\n\n  /**\n   * Sets the vertical offset, in pixels, of the {@link FloatingActionButton} being cradled. An\n   * offset of 0 indicates the vertical center of the {@link FloatingActionButton} is positioned on\n   * the top edge.\n   */\n  void setCradleVerticalOffset(@FloatRange(from = 0f) float cradleVerticalOffset) {\n    if (cradleVerticalOffset < 0) {\n      throw new IllegalArgumentException(\"cradleVerticalOffset must be positive.\");\n    }\n    this.cradleVerticalOffset = cradleVerticalOffset;\n  }\n\n  float getFabCradleMargin() {\n    return fabMargin;\n  }\n\n  void setFabCradleMargin(float fabMargin) {\n    this.fabMargin = fabMargin;\n  }\n\n  float getFabCradleRoundedCornerRadius() {\n    return roundedCornerRadius;\n  }\n\n  void setFabCradleRoundedCornerRadius(float roundedCornerRadius) {\n    this.roundedCornerRadius = roundedCornerRadius;","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/bottomappbar/BottomAppBarTopEdgeTreatment.java#L215-L251","documentation":"BottomAppBarTopEdgeTreatment.setCradleVerticalOffset(float) defines the vertical offset in pixels of the cradled FloatingActionButton relative to the BottomAppBar's top edge. The treatment only accepts non-negative values (@FloatRange(from = 0f)); a negative offset throws IllegalArgumentException.","triggerScenarios":"Calling setCradleVerticalOffset with a negative float; reading a value from dimension resources, animations, or user input that computes to < 0 and passing it through; deriving the offset from a scroll position that can go negative.","commonSituations":"Animators that interpolate the offset and briefly produce negative interpolated values; binding the offset to a calculation like (anchorY - fabY) that flips sign on small screens; migrating from an older version where negative offsets were silently clamped.","solutions":["Clamp the value to Math.max(0f, offset) before calling setCradleVerticalOffset.","Fix the source calculation so it cannot produce a negative offset (recheck the sign/direction of the math).","If animating, use Animator.setEvaluator or an ArgbEvaluator-equivalent clamping approach so intermediate values stay >= 0."],"exampleFix":"// before\nfloat offset = computedOffset; // may be negative\nbottomAppBarTopEdgeTreatment.setCradleVerticalOffset(offset);\n\n// after\nbottomAppBarTopEdgeTreatment.setCradleVerticalOffset(Math.max(0f, computedOffset));","handlingStrategy":"validation","validationCode":"float safeOffset = Math.max(0f, computedCradleOffset);\ntopEdgeTreatment.setCradleVerticalOffset(safeOffset);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp all runtime-derived offsets to >= 0.","When animating the offset, verify the evaluator cannot emit negative interpolation values."],"tags":["bottomappbar","shape-treatment","illegal-argument","validation"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}