Skip to content

Interactive viewer mouse controls crash with MuJoCo >= 3.11 (gymnasium mjv_moveCamera incompatibility) #103

Description

@ratheron

Summary

Mouse interaction (drag to rotate/pan, scroll to zoom) in the interactive sim.render(mode="human") window crashes with a TypeError when using MuJoCo >= 3.11.0 together with gymnasium 1.3.0. Offscreen rendering (rgb_array, depth_array, rgbd_tuple) is unaffected.

This is not a bug in Crazyflow itself, but it affects every user on our current lockfiles (mujoco 3.12.0 + gymnasium 1.3.0), so we should decide how to handle it.

Reproduction

pixi run -e tests python examples/plugins/disturbance.py

Then drag the camera with the mouse in the viewer window.

Traceback
  File "crazyflow/sim/sim.py", line 248, in render
    return self.viewer.render(mode)
  File ".../gymnasium/envs/mujoco/mujoco_rendering.py", line 600, in _cursor_pos_callback
    mujoco.mjv_moveCamera(
        self.model, action, dx / width, dy / height, self.scn, self.cam
    )
TypeError: mjv_moveCamera(): incompatible function arguments. The following argument types are supported:
    1. (m: MjModel, action: int, reldx: float, reldy: float, cam: MjvCamera) -> None

Root cause

  • MuJoCo 3.11.0 (2026-07-28) made a breaking API change: "Removed unneeded mjvScene argument from mjv_moveCamera" (changelog). The function now takes 5 arguments instead of 6.
  • gymnasium 1.3.0 (2026-04-22, latest release on PyPI) predates that change and still passes self.scn in WindowViewer._cursor_pos_callback and _scroll_callback.
  • Crazyflow only uses gymnasium.envs.mujoco.mujoco_rendering.MujocoRenderer (crazyflow/sim/sim.py) and never calls mjv_moveCamera directly.

Gymnasium has already fixed this on main in Farama-Foundation/Gymnasium#1678 (merged 2026-08-29) via a _MUJOCO_CAMERA_LEGACY_MODE version check, but no release containing the fix exists yet.

Options

  1. Do nothing and wait for the next gymnasium release. Simplest; the GUI stays broken for everyone on a fresh install until then.
  2. Constrain MuJoCo in pyproject.toml: "mujoco>=3.3.0,<3.11" and "mujoco-mjx>=3.3.0,<3.11", re-lock, and lift the bound once gymnasium ships the fix. Note that a !=3.11.*,!=3.12.* exclusion (like the existing jax!=0.10.2) doesn't really fit: the incompatibility is between a pair of packages, and every future MuJoCo release would be broken too until gymnasium releases.
  3. Add a temporary compatibility shim in sim.py for mode="human": if mujoco.__version__ >= 3.11 and gymnasium's mujoco_rendering has no _MUJOCO_CAMERA_LEGACY_MODE, wrap the viewer's cursor/scroll callbacks to call mjv_moveCamera without scn. ~15 lines, keeps MuJoCo 3.12 available, removable when gymnasium releases.
  4. Drop the gymnasium renderer and move to mujoco.viewer (passive viewer) for human mode. Larger change, but removes a dependency on gymnasium internals that has now bitten us. Would need to replace add_marker usage in crazyflow/sim/visualize.py.

I would go for 2. Is there a reason we have bumped Python to 3.14 @amacati and thus allowed for newer mujoco versions?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions