20 landmines between you and a reproducible VLA eval. Symptom → fix, grouped by when it
bites. This is the quick-reference layer; the chronological story is
FRICTION_LOG.md and the deep per-topic detail is
NOTES.md.
Build & environment (bites at image build / first import — loudly)¶
#
Symptom
Fix
1
"LIBERO conflicts with modern stacks"
Myth — its setup.py installs nothing; the scary requirements.txt is training-only. One env works
2
EGL / "failed to create GL context"
Set MUJOCO_GL=egl (macOS: cgl) before any robosuite/mujoco import
CUDA runtime bases ship no compiler; Modal's add_python is clang-built → apt install build-essential clang
5
egl_probe: "CMake must be installed"
apt install cmake (hf-libero dep)
6
EOFError on import libero in a container
LIBERO prompts input() on first import — bake its config at image build: printf 'n\n' \| python -c 'import libero.libero'. (Survived into the hf-libero wheel, too)
uv lock/uv run "No solution found" on a project that pip-installs fine
uv resolves every extra for every python/platform — one exotic (git-dep) extra bricks the lock for all users. Scope with [tool.uv] environments, park the exotic stack behind a pointer extra, pin .python-version (see FRICTION_LOG.md #22)
Silent success-rate killers (nothing raises; the number is just wrong)¶
#
Symptom
Fix
8
0% SR, every episode runs to the step cap
RLDS gripper convention (0..1, ~1=open) fed raw into LIBERO (−1=open/+1=close): the hand can never open. Normalize [0,1]→[−1,1], binarize, invert (OpenVLA's own eval utils)
9
SR quietly below published
Apply center-crop at eval (0.9 area, resize back) when the checkpoint trained with crop augmentation
ValueError: executing action in terminated episode mid-sweep
env.reset()every episode: set_init_state alone leaves robosuite's step counter running across episodes; ~cumulative step 1000 the env poisons itself. Invisible in short runs — and it degrades outcomes before it crashes
16
torch.from_numpy: "negative strides are not supported"
The 180° de-rotation is a reversed view — np.ascontiguousarray first
17
A 500-step episode in a 250-cap suite
episode_id names the episode spec (identical across policies by design) — group by (policy_type, episode_id) or you chimera trajectories
18
mj_fullM() TypeError / scipy-vs-numpy conflict after a rebuild
Unpinned transitives drift with the build date (mujoco>=3.10 breaks robosuite 1.4.x bindings; scipy>=1.18 wants numpy>=2) → pin the sweep-verified set: mujoco==3.9.0, scipy==1.15.3
19
Detached Modal sweep dies when the laptop does
modal run -d survives network drops, not client teardown → modal deploy + Function.spawn(), and make sweeps resumable (part filename = deterministic episode id)
None of the silent ones raise. All of them read as "the model is bad."