#7793·IsaacLab

[Bug Report] DelayBuffer.set_time_lag leaves invalid state after raising ValueError

Author: peachtree0222Created Sep 14, 2026Updated Sep 17, 2026

Describe the bug

DelayBuffer.set_time_lag() validates the requested lags only after writing them into _time_lags and recomputing _min_time_lag / _max_time_lag. When the method raises for a negative lag or a lag above history_length, the rejected value remains live.

For a buffer with history length 4, this sequence demonstrates the broken error contract:

python
buffer.set_time_lag(torch.tensor([0, 1, 2, 3, 4]))
try:
    buffer.set_time_lag(5, batch_ids=[2])
except ValueError:
    pass
print(buffer.time_lags, buffer.max_time_lag)

The output is [0, 1, 5, 3, 4] and 5, rather than the prior valid configuration. If the caller catches the validation error and continues, subsequent compute() calls silently clamp that impossible delay to the oldest buffered sample.

Steps to reproduce

  1. Check out a8b4da3c29ae528b39d4b3c9444d782ce58d886d.
  2. Run poc/repro.py with Isaac Lab on PYTHONPATH.
  3. Observe that the method raises and then the final state assertion fails.
before: [0, 1, 2, 3, 4] min=0 max=4
ValueError: The maximum time lag cannot be larger than the history length. Received: 5
after:  [0, 1, 5, 3, 4] min=0 max=5

Expected behavior: validation failure leaves time_lags, min_time_lag, and max_time_lag unchanged.

Reproduction files:

delay-buffer-invalid-lag-corrupts-state-poc.zip

System Info

  • Commit: a8b4da3c29ae528b39d4b3c9444d782ce58d886d (develop); same write-before-validation order at b0542fe2d45bf91c4e1d9ef6952b9c709c80b4e8 (main)
  • Isaac Sim Version: not required; current project dependency is 6.1.0
  • OS: Ubuntu 24.04.5 LTS
  • GPU: not used
  • CUDA / driver: not used; driver 595.84 present
  • Python / Torch: Python 3.12.13, Torch 2.8.0+cpu

Additional context

The mutation-before-validation sequence is in DelayBuffer.set_time_lag. One production caller is DelayedPDActuator.reset.

The patch validates a cloned candidate and commits with copy_() only after success. This also preserves tensor identity for any existing readers. Issue #4274 is related to buffer performance, not this transactional error behavior.

Checklist

  • I have checked that there is no similar issue in the repo (bounded issue and PR search repeated on 2026-09-12; repeat immediately before filing)
  • I have checked that the issue is not in running Isaac Sim itself and is related to the repo

Acceptance Criteria

  • A rejected scalar lag leaves all existing per-batch lags unchanged.
  • A rejected tensor lag leaves all existing per-batch lags unchanged.
  • min_time_lag and max_time_lag remain consistent with time_lags after success or failure.
  • Valid full and subset updates retain existing behavior on CPU and CUDA.