From 3f7436ff8a366227866e72436d76dff768424923 Mon Sep 17 00:00:00 2001 From: Pepijn Date: Tue, 12 May 2026 14:50:22 +0200 Subject: [PATCH] fix(smolvla2): use TransitionKey enum (not .value) as transition keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``EnvTransition`` is declared as a ``TypedDict`` keyed by ``TransitionKey.OBSERVATION.value`` (the string ``'observation'``), but every concrete ``ProcessorStep`` in the pipeline indexes the transition with the enum *member* (``transition[TransitionKey. OBSERVATION]`` / ``transition.get(TransitionKey.OBSERVATION)``). Those are two different keys in a Python dict — string key vs enum key — so steps couldn't find the observation we'd placed under the string variant, and bailed every tick with ``ObservationProcessorStep requires an observation in the transition``. Build the transition with the enum members directly. Matches how ``BatchProcessor``, ``RelativeActionProcessor``, ``HilProcessor``, etc. read the dict. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../scripts/lerobot_smolvla2_runtime.py | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/lerobot/scripts/lerobot_smolvla2_runtime.py b/src/lerobot/scripts/lerobot_smolvla2_runtime.py index f59120936..c5d7dfb04 100644 --- a/src/lerobot/scripts/lerobot_smolvla2_runtime.py +++ b/src/lerobot/scripts/lerobot_smolvla2_runtime.py @@ -629,21 +629,28 @@ def _build_robot_observation_provider( return None if preprocessor is not None: - transition: dict[str, Any] = { - TransitionKey.OBSERVATION.value: obs_tensors, - TransitionKey.ACTION.value: None, - TransitionKey.REWARD.value: None, - TransitionKey.DONE.value: None, - TransitionKey.TRUNCATED.value: None, - TransitionKey.INFO.value: None, - TransitionKey.COMPLEMENTARY_DATA.value: {}, + # ``EnvTransition``'s TypedDict is declared with + # ``TransitionKey.OBSERVATION.value`` as keys, but every + # ProcessorStep in the pipeline does + # ``transition.get(TransitionKey.OBSERVATION)`` / indexes + # with the *enum member* — not the string ``.value``. Build + # the dict with enum keys so the steps actually find the + # observation. + transition: dict[Any, Any] = { + TransitionKey.OBSERVATION: obs_tensors, + TransitionKey.ACTION: None, + TransitionKey.REWARD: None, + TransitionKey.DONE: None, + TransitionKey.TRUNCATED: None, + TransitionKey.INFO: None, + TransitionKey.COMPLEMENTARY_DATA: {}, } try: transition = preprocessor(transition) except Exception as exc: # noqa: BLE001 logger.warning("preprocessor failed on robot observation: %s", exc) return None - obs_tensors = transition.get(TransitionKey.OBSERVATION.value) or {} + obs_tensors = transition.get(TransitionKey.OBSERVATION) or {} observation = { k: v