FyroxEngine/Fyrox · error

Unable to apply position, because underlying type is not…

Error message

Unable to apply position, because underlying type is not Vector2!

What it means

UiAnimation::apply maps animation track values to widget properties. The Position binding requires the track to hold Vector2 values; if the track holds any other value type, the engine cannot apply it and logs this error (no panic).

Solutions

  1. Ensure Position tracks are created with TrackValue::Vector2 values
  2. Verify the track's value type when constructing the animation
  3. Add a match/guard on the TrackValue variant before binding to Position

Example fix

// before
track.set_binding(ValueBinding::Position);
track.add_value(TrackValue::Real(1.0));
// after
track.set_binding(ValueBinding::Position);
track.add_value(TrackValue::Vector2(Vector2::new(10.0, 10.0)));
Defensive patterns

Strategy: type-guard

Validate before calling

match track_value { TrackValue::Vector2(_) => apply_ok(), _ => fix_track_type() }

Type guard

fn is_vector2_track(v: &TrackValue) -> bool { matches!(v, TrackValue::Vector2(_)) }

Prevention

When it happens

Trigger: An animation track bound to ValueBinding::Position whose TrackValue is not TrackValue::Vector2 (e.g. created with f32/bool values).

Common situations: Building UI animations programmatically and pushing wrong-typed keyframes into the position track; importing/retargeting animations between widgets with mismatched track types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/5273ae9cfa26599e. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-ui/src/animation.rs:126

    }
}

/// Extension trait for [`BoundValueCollection`].
pub trait BoundValueCollectionExt {
    /// Tries to set each value from the collection to the respective property (by binding) of the
    /// given widget.
    fn apply(&self, node_ref: &mut UiNode);
}

impl BoundValueCollectionExt for BoundValueCollection {
    fn apply(&self, node_ref: &mut UiNode) {
        for bound_value in self.values.iter() {
            match bound_value.binding {
                ValueBinding::Position => {
                    if let TrackValue::Vector2(v) = bound_value.value {
                        node_ref.set_desired_local_position(v);
                    } else {
                        Log::err(
                            "Unable to apply position, because underlying type is not Vector2!",
                        )
                    }
                }
                ValueBinding::Scale => Log::warn("Implement me!"),
                ValueBinding::Rotation => Log::warn("Implement me!"),
                ValueBinding::Property {
                    name: ref property_name,
                    value_type,
                } => bound_value.apply_to_object(node_ref, property_name, value_type),
            }
        }
    }
}

/// Animation player is a node that contains multiple animations. It updates and plays all the animations.
/// The node could be a source of animations for animation blending state machines. To learn more about
/// animations, see [`Animation`] docs.

View on GitHub (pinned to 76c91aad8e)