airbnb/lottie-android · error · IllegalArgumentException
You must provide a static value in the constructor , call se
Error message
You must provide a static value in the constructor , call setValue, or override getValue.
What it means
Thrown by LottieRelativeFloatValueCallback.getOffset() when the internal value field is null. This callback is designed to add a relative offset to the animation's interpolated value, but it needs a base offset value to work with. The value can be set via the constructor (passing a Float), via setValue(), or by overriding getOffset()/getValue() entirely. If none of these are done, getOffset() has no offset to return and throws.
Source
Thrown at lottie/src/main/java/com/airbnb/lottie/value/LottieRelativeFloatValueCallback.java:34
public LottieRelativeFloatValueCallback(@NonNull Float staticValue) {
super(staticValue);
}
@Override
public Float getValue(LottieFrameInfo<Float> frameInfo) {
float originalValue = MiscUtils.lerp(
frameInfo.getStartValue(),
frameInfo.getEndValue(),
frameInfo.getInterpolatedKeyframeProgress()
);
float offset = getOffset(frameInfo);
return originalValue + offset;
}
public Float getOffset(LottieFrameInfo<Float> frameInfo) {
if (value == null) {
throw new IllegalArgumentException("You must provide a static value in the constructor " +
", call setValue, or override getValue.");
}
return value;
}
}
View on GitHub (pinned to 05ea92e903)
Solutions
- Pass a static offset value to the constructor: new LottieRelativeFloatValueCallback(0.5f)
- Call setValue(offset) on the callback instance before or during animation
- Override getOffset(LottieFrameInfo<Float>) in a subclass to compute the offset dynamically without needing a static value
- If you want absolute value control (not relative), use LottieValueCallback<Float> instead of LottieRelativeFloatValueCallback
Example fix
// before:
// LottieRelativeFloatValueCallback<Float> cb = new LottieRelativeFloatValueCallback<>();
// lottieAnimationView.addValueCallback(keyPath, property, cb); // throws on first frame
// after option 1: provide a static offset in the constructor
// LottieRelativeFloatValueCallback cb = new LottieRelativeFloatValueCallback(0.5f);
// after option 2: call setValue
// cb.setValue(0.5f);
// after option 3: override getOffset for dynamic offset
LottieRelativeFloatValueCallback cb = new LottieRelativeFloatValueCallback() {
@Override public Float getOffset(LottieFrameInfo<Float> frameInfo) {
return frameInfo.getInterpolatedKeyframeProgress() * 100f; // dynamic
}
}; Defensive patterns
Strategy: validation
Validate before calling
// Ensure value is set before using the callback
LottieRelativeFloatValueCallback createSafeCallback(float offset) {
return new LottieRelativeFloatValueCallback(offset); // non-null static value
}
// Or validate before use:
void ensureValueSet(LottieRelativeFloatValueCallback cb) {
if (cb.getValue(new LottieFrameInfo<>()) == null && !hasOverride(cb)) {
cb.setValue(0f); // provide a default offset
}
} Type guard
// Check if the callback has a usable value before applying
boolean isCallbackReady(LottieRelativeFloatValueCallback cb) {
try {
cb.getOffset(new LottieFrameInfo<Float>());
return true;
} catch (IllegalArgumentException e) {
return false;
}
} Try / catch
try {
lottieAnimationView.addValueCallback(keyPath, property, callback);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("static value")) {
callback.setValue(0f); // provide default offset
lottieAnimationView.addValueCallback(keyPath, property, callback);
} else throw e;
} Prevention
- Always pass a Float value to the LottieRelativeFloatValueCallback constructor
- Call setValue() if you used the no-arg constructor
- Override getOffset() for dynamic offsets instead of relying on a static value
When it happens
Trigger: Creating a LottieRelativeFloatValueCallback with the no-arg constructor (new LottieRelativeFloatValueCallback()) and using it as a value callback without calling setValue() or overriding getOffset(). When Lottie evaluates the animation and calls getValue() -> getOffset(), the null check at line 33 fires the throw at line 34.
Common situations: A developer creates the callback with the no-arg constructor intending to override getOffset() later but forgets. Subclassing LottieRelativeFloatValueCallback and not overriding getOffset() or providing a value. Copying example code that used the constructor overload but switching to no-arg. Refactoring that removed a setValue() call.
Related errors
- You must provide a static value in the constructor , call se
- You must provide a static value in the constructor , call se
- LottieAnimator does not support getStartDelay.
- LottieAnimator does not support setStartDelay.
- LottieAnimator does not support setDuration.
AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14).
Data as JSON: /api/errors/bc62169ba41bc529.
Report an issue: GitHub.