stride3d/stride · error · InvalidOperationException

A Gear constraint requires two rigidbodies.

Error message

A Gear constraint requires two rigidbodies.

What it means

GearConstraintDesc.Build() builds a Bullet gear constraint, which by definition couples two rigidbodies via an axis and ratio. If bodyB is null it throws InvalidOperationException because a gear constraint cannot exist with a single body.

Solutions

  1. Assign a valid second RigidbodyComponent as BodyB on the constraint before the simulation starts
  2. Verify the constraint's second body reference is not null after scene load
  3. If you only have one body, use a different constraint type (e.g. a joint) instead of Gear

Example fix

// before
rigidbody.Constraints.Add(new GearConstraintDesc { Ratio = 2f });
// after
var gear = new GearConstraintDesc { Ratio = 2f, Body = otherRigidbody };
rigidbody.Constraints.Add(gear); // Body (second rigidbody) must be set
Defensive patterns

Strategy: validation

Validate before calling

if (desc.Body == null) throw new ArgumentException("Gear constraint requires a second rigidbody (Body).");

Try / catch

try { constraint.Build(bodyA, bodyB); }
catch (InvalidOperationException) { /* bodyB missing; fix config */ }

Prevention

When it happens

Trigger: Assigning a GearConstraintDesc to a RigidbodyComponent's Constraints without assigning a second Body (BodyB), or leaving the constraint's second body unassigned at build time.

Common situations: Configuring constraints in the editor/scene where only one body is wired up; copying constraint configs where the paired body reference was lost; dynamic spawning where bodyB is set later than Build.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/2e50f8745805472a. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Physics/Constraints/GearConstraintDesc.cs:57

        /// <userdoc>
        /// Axis on which the gear will rotate relative to body B.
        /// </userdoc>
        [Display(1)]
        public Quaternion AxisInB { get; set; } = Quaternion.Identity;

        /// <summary>
        /// Size ratio between the gears (rotating a bigger gear will rotate smaller gear quicker).
        /// </summary>
        /// <userdoc>
        /// Size ratio between the gears (rotating a bigger gear will rotate smaller gear quicker).
        /// </userdoc>
        [Display(2)]
        public float Ratio { get; set; } = 1;

        /// <inheritdoc/>
        public Constraint Build(RigidbodyComponent bodyA, RigidbodyComponent bodyB)
        {
            if (bodyB == null) throw new System.InvalidOperationException("A Gear constraint requires two rigidbodies.");

            var axis = Vector3.UnitX;
            AxisInA.Rotate(ref axis);
            var frameA = Matrix.Translation(axis);

            axis = Vector3.UnitX;
            AxisInB.Rotate(ref axis);
            var frameB = Matrix.Translation(axis);

            var gear = Simulation.CreateConstraint(ConstraintTypes.Gear, bodyA, bodyB, frameA, frameB) as GearConstraint;

            gear.Ratio = Ratio;

            return gear;
        }
    }
}

View on GitHub (pinned to 96fad776d2)