Repository navigation
fix(js): drop a headless subgroup before FIRST_OBJECT (backport #5019) - #5120
Conversation
On drafts 14-17 the subgroup header has no FIRST_OBJECT bit, so a stream that starts at the live edge reached Frame.decode with a non-zero first delta and failed the group. Run release's existing first-object peek on those drafts too, and drop the stream so the subscription resumes at the next group. (cherry picked from commit 321fc02, adapted) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Automated review of The adaptation is sound: on drafts 14-17 the subscriber now peeks the first object id, drops a stream whose first id is non-zero (keeping the subscription up), and still treats an empty stream as an empty group. Draft-18+ behavior is unchanged since No blocking issues. Non-blocking:
Verdict: MERGE once CI is green. This is an automated review, not the maintainer's decision |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 1afd492
No new actionable defect found. Reusing the existing non-consuming peek is a suitably small release backport: js/net/src/ietf/subscriber.ts:1053–1068 drops a legacy non-zero first ID before opening the group, preserves clean empty groups, and leaves later gaps and draft-18+ contradictions on the failure path. The finally block still accounts for dropped streams. The version predicate matches header decoding; package exports and wire encoding remain unchanged.
The new regression distinguishes dropping from opening a failed group and checks recovery plus later-gap handling. I agree with the non-blocking empty-stream test suggestion already raised here; no duplicate inline comment.
Verification limits: GitHub-only static review of all three changed files, surrounding receive/Reader logic, and package exports. I did not run builds, tests, or live relay interoperability. Check, Release JS, and Audio quality workflows were still running at publication.
Backport of #5019 (
321fc0274onmain) torelease, for the 0.4.x@moq/netline. The 0.4.3 bump in #5119 should merge after this.Problem
On drafts 14-17 the subgroup header has no
FIRST_OBJECTbit, so decode forcesfirstObjecton. A stream that starts at the live edge carries a non-zero first object delta,Frame.decoderefuses it, and the group fails, which resets the subscription. This is the rust-to-js failure through moqx (draft-16) and moxygen (draft-14). Draft-18+ peers are unaffected: a cleared bit already takes the drop path.Adaptation
mainthrows a newObjectIdGapfromFrame.decodeand drops the stream in the catch.releasealready peeks the first object id whenFIRST_OBJECTis clear, so this backport runs that same peek when!hasFirstObjectBit(version)instead of cherry-picking the catch path. A non-zero first id drops the stream and the subscription stays up for the next group.An empty stream on drafts 14-17 still yields an empty group, matching
main. A gap after the first object still fails that group, and a draft-18 header that claims object 0 and then starts elsewhere still fails it.Public API and wire impact
hasFirstObjectBitis exported withinietf/object.tsonly; it is not re-exported from the package entry.Tests
a draft without FIRST_OBJECT drops a subgroup that starts mid-group(draft-16). It fails onreleasewithout the fix (group 3 is opened and failed) and passes with it.bun testinjs/net: 1114 pass, 0 fail.just checkagainstorigin/release: pass.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code