Skip to content

fix(bag): stop infinite Range re-fetch loop when loading remote .bag files - #46

Merged
joaner merged 1 commit into
ioai-tech:mainfrom
joaner:fix/bag-remote-size-loop
Aug 11, 2026
Merged

fix(bag): stop infinite Range re-fetch loop when loading remote .bag files#46
joaner merged 1 commit into
ioai-tech:mainfrom
joaner:fix/bag-remote-size-loop

Conversation

@joaner

@joaner joaner commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remote .bag loading called @foxglove/rosbag's Filelike.size() synchronously internally (this._file.size() - fileOffset, never awaited), but bag.worker.ts's remote adapter exposed an async/BigInt size(). The un-awaited subtraction silently became NaN, which CachedFilelike can never mark as satisfied — it kept re-deriving and re-fetching the same ~50MiB block forever while Bag.open() never resolved.
  • Root-cause fix: resolve the real byte count once up front and expose a synchronous size(), matching the library's real Filelike contract; import that type directly (dropping an unsafe as cast) so a future mismatch is a compile error again.
  • Defense in depth in CachedFilelike: reject non-finite/negative offsets and lengths at the read()/prefetch() entry points instead of silently enqueueing unsatisfiable requests, and bound the connection-error retry count so a persistently (but not rapidly) failing fetch can no longer retry forever.
  • Bump to v1.7.9.

Test plan

  • npm run lint
  • npm test (666 tests, incl. new regression coverage in CachedFilelike.test.ts and remoteBagReadable.test.ts)
  • npx tsc -b --noEmit
  • Manual end-to-end repro against a real 480MB rgbd_dataset_freiburg1_xyz.bag served locally over HTTP Range: before the fix, initialize() hung past 12s and emitted a literal Range: bytes=NaN-NaN request; after the fix it resolves in ~500ms with the correct topic list and no duplicate/invalid Range requests.
  • CI (lint / build / test / e2e)

…files

@foxglove/rosbag's Filelike.size() must be synchronous (number), but the
remote adapter in bag.worker.ts exposed an async/BigInt size(), which
turned the library's un-awaited `size() - offset` arithmetic into NaN.
A NaN-bounded read() can never be marked satisfied by CachedFilelike, so
it kept re-deriving and re-fetching the same ~50MiB block forever while
Bag.open() never resolved — reproduced end-to-end against a real 480MB
bag file (initialize() hung past 12s and even emitted a literal
`Range: bytes=NaN-NaN` request before the fix; resolves in ~500ms after).

Also hardens CachedFilelike against this whole class of bug: reject
non-finite/negative offsets and lengths at the read()/prefetch() entry
points instead of silently enqueueing unsatisfiable requests, and bound
the connection-error retry count so a persistently (but not rapidly)
failing fetch can no longer retry forever.

Bump to v1.7.9.
@joaner
joaner merged commit e9318b9 into ioai-tech:main Aug 11, 2026
2 checks passed
@joaner
joaner deleted the fix/bag-remote-size-loop branch August 11, 2026 01:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant