Skip to content

moq-lite: fix AnnounceInterest.exclude_hop overflow on JS side#1427

Merged
kixelated merged 1 commit into
mainfrom
moq-lite/excludehop-overflow
May 18, 2026
Merged

moq-lite: fix AnnounceInterest.exclude_hop overflow on JS side#1427
kixelated merged 1 commit into
mainfrom
moq-lite/excludehop-overflow

Conversation

@kixelated
Copy link
Copy Markdown
Collaborator

Summary

Browsers connecting to a fresh relay over `moq-lite-04` were getting their session torn down ~7ms after the handshake, with `WebTransportError: The session is closed` cascading through every in-flight stream. Root cause was a field-width mismatch in JS.

The Rust relay sends its session-level Origin id (62-bit, ~10^18) as `AnnounceInterest.exclude_hop` so peers can skip reflected announces. The JS decoder read it via `r.u53()`, which throws on anything > `2^53-1`. The throw inside `#runBidi` was caught by `stream.writer.reset(err)` with an `Error` object as the reason, which Chrome's WebTransport surfaces as a session-level abort (`remote error: code=0`). Everything else followed from there.

JS

  • `AnnounceInterest.excludeHop` is now `bigint`, encoded/decoded via `u62`. (`js/lite/src/lite/announce.ts`)
  • `Subscriber.#runAnnounced` passes `this.origin` as `excludeHop`, matching the Rust subscriber's `self.self_origin.id`. (`js/lite/src/lite/subscriber.ts`)
  • `Reader.u53` / `Writer.u53` downgrade overflow from `throw` to `console.warn` (precision is lost, the warning surfaces the value). A stray u64 on the wire can no longer tear down a stream/session. (`js/lite/src/stream.ts`)

Rust

  • `Origin::random` temporarily caps the random id at 53 bits so older deployed `@moq/lite` bundles (still on the buggy u53 decoder) survive a fresh relay. Restore to 62 bits once the JS fix has propagated. (`rs/moq-lite/src/model/origin.rs`)

Version bumps

  • `@moq/lite` 0.2.3 → 0.2.4
  • `moq-lite` 0.16.2 → 0.16.3
  • `moq-relay` 0.11.2 → 0.11.3

Test plan

  • `just check` passes
  • `just dev`: web demo connects, no `session is closed` cascade, bbb stream renders
  • `just web serve https://cdn.moq.dev/demo\` against a relay built from this PR: connection stays up
  • Older `@moq/lite` bundles still work against a relay from this PR (origin id capped to 53 bits)

Probe-lifecycle cleanups landed separately in #1426.

🤖 Generated with Claude Code

The Rust relay encodes `AnnounceInterest.exclude_hop` as a 62-bit Origin
id, but the JS client was decoding it via `r.u53()`, which throws
"value larger than 53-bits" for any peer Origin > 2^53-1. The throw
inside `#runBidi` was caught by `stream.writer.reset(err)` with an
Error object as the reason, which Chrome's WebTransport surfaces as a
session-level abort (`remote error: code=0`). The resulting cascade
tore down the entire connection right after the announce handshake.

JS:
- `AnnounceInterest.excludeHop` is now `bigint`, encoded/decoded via
  `u62` to match the wire format and the Rust struct.
- `Subscriber.#runAnnounced` passes `this.origin` as `excludeHop`,
  matching the Rust subscriber's `self.self_origin.id` behavior.
- `Reader.u53` / `Writer.u53` downgrade overflow from throw to warn
  so a stray u64 on the wire can never tear down a stream/session
  again. Precision is lost; the warning surfaces the value.

Rust:
- `Origin::random` temporarily caps the random id at 53 bits so older
  `@moq/lite` bundles (still on the buggy u53 decoder) survive a fresh
  relay. Restore to 62 bits once the JS fix has propagated.

Version bumps:
- @moq/lite 0.2.3 -> 0.2.4
- moq-lite 0.16.2 -> 0.16.3
- moq-relay 0.11.2 -> 0.11.3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kixelated kixelated merged commit f41a89d into main May 18, 2026
1 check passed
@kixelated kixelated deleted the moq-lite/excludehop-overflow branch May 18, 2026 10:58
@moq-bot moq-bot Bot mentioned this pull request May 18, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 837d4050-d903-46c8-84c9-5053adfdddaf

📥 Commits

Reviewing files that changed from the base of the PR and between 63feeec and 2efc270.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • js/lite/package.json
  • js/lite/src/lite/announce.ts
  • js/lite/src/lite/subscriber.ts
  • js/lite/src/stream.ts
  • rs/moq-lite/Cargo.toml
  • rs/moq-lite/src/model/origin.rs
  • rs/moq-relay/Cargo.toml

Walkthrough

This PR extends AnnounceInterest to support 62-bit excludeHop values as 64-bit JavaScript bigints while maintaining temporary 53-bit compatibility with existing JS clients. The core type change updates serialization to u62 varint encoding. Subscriber integration passes the connection's origin field for hop-chain self-exclusion. Stream reader/writer u53 methods now warn instead of throwing on overflow. Rust origin generation is capped to 53 bits for JS compatibility. All package versions are incremented to reflect the changes.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch moq-lite/excludehop-overflow
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch moq-lite/excludehop-overflow

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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