[GH-ISSUE #6576] [Bug] Valid nested protobuf messages containing groups lose their nested-message interpretation #3966

Closed
opened 2026-10-31 00:45:39 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6576

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

The public inspect-web-network-capture CLI decodes 13 18 01 14 as a complete protobuf message: field 2 is a group containing varint field 3 with value 1. Putting those same four bytes inside a length-delimited field (0a 04 13 18 01 14) removes nested-message from that field's interpretation candidates. The returned alternatives include UTF-8, packed varint, packed fixed32 and bytes, but omit the valid nested-message reading. Both bodies report complete decoding.

An ordinary nested message (0a 02 18 01) retains the nested-message candidate. These three cases ran together through the public CLI once, before drafting. This is a static capture-analysis issue; no server or captured application ran.

Reproduction

Use the audited source checkout with its locked dependencies and built runtime. The executed fixture generator used the repository's inert HAR fixture helper:

import { writeFile } from 'node:fs/promises';
import { protobufHar } from './tests/fixtures/protobufCapture.ts';
await writeFile('nested-group.har', protobufHar(
  Buffer.from('13180114', 'hex'),
  'application/x-protobuf',
  [Buffer.from('0a0413180114', 'hex'), Buffer.from('0a021801', 'hex')],
));

The imports/output above are expressed relative to the checkout for portability; the executed generator lived outside the checkout and used absolute paths to the same fixture helper and HAR output. Run it with the locked tsx, then inspect the three entries:

node scripts/rea.mjs inspect-web-network-capture "$PWD/nested-group.har" har --record 0 --record 1 --record 2 --format json

The executed CLI used an absolute temporary HAR path and Node 24.22.1. In normalized_result.records, compare each body's protobuf[0].fields and status. A smaller production wire-decoder probe also observed the missing candidate before this CLI check; it was not a post-draft rerun.

Expected behavior

A length-delimited payload that is a syntactically valid supported protobuf message should retain nested-message among its possible interpretations, including when it contains a valid proto2 group. Keep the alternatives ambiguous; do not claim a schema or recursively expand the candidate.

The documented capture contract describes group support and length-delimited nested-message candidates. The executed standalone-body control establishes that this exact group payload is already supported by the wire decoder.

Impact and scope

P2: the interpretation list omits a valid structural reading for length-delimited messages containing groups, which can misdirect schema-free analysis. Original payload bytes and ranges remain intact. The observed scope is the three synthetic HAR records on Linux; no evidence loss or target execution occurred. NOT_ENOUGH_INFO: prevalence in real captures and other producer formats.

A bounded workaround is to copy the retained payload bytes into a separate raw protobuf capture body: the standalone control decoded those exact bytes and exposed the group and child. This requires manual extraction; it does not repair the original interpretation list.

REA version

Main source 46111dd091f2ae01baab9eb119b53b9bd309a05b, package metadata 6.7.0. This is a main-only finding. The audited protobuf implementation does not exist at the latest published rea-agents-6.7.0 tag (27dc42d10249f0410904a75c0997842eb03b931c); no published-package failure is claimed.

Runtime and platform

Node.js v24.22.1 for the public CLI; Linux x86_64. Dependencies and source build used the repository-pinned Node/npm versions. The smaller wire probe used supported Node.js v26.12.1. No external capture provider was invoked.

Target and artifact context

An inert three-entry HAR with base64 response bodies, MIME type application/x-protobuf, and the exact protobuf bytes above. URLs use example.invalid; no private target data.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Reduced from the executed public CLI result:

[
  {"ordinal":0,"status":"complete","fields":[{"number":2,"wire_type":"group","parent_index":null},{"number":3,"wire_type":"varint","parent_index":0}]},
  {"ordinal":1,"status":"complete","fields":[{"number":1,"wire_type":"len","parent_index":null,"interpretations":["utf8-string","packed-varint","packed-fixed32","bytes"]}]},
  {"ordinal":2,"status":"complete","fields":[{"number":1,"wire_type":"len","parent_index":null,"interpretations":["utf8-string","nested-message","packed-varint","bytes"]}]}
]

All three selected records also received protobuf_coverage.status: "complete". Complete wire coverage is not itself the bug; the missing valid interpretation in record 1 is the discrepancy.

Typed outcome or recovery expected

Record 1 should include nested-message without dropping its other valid candidates. Malformed or mismatched groups should continue to fail the candidate check.

Analysis or suspected cause

Source-derived: messageCandidate accepts wire types 0, 1, 2 and 5, returning false for every group start. The full decoder supports groups. These two syntax interpretations disagree on the same bytes.

Additional context

Searched the supplied open-issue inventory and all-state GitHub issue searches for protobuf and protobuf group. No matching report was found. Open #6118 concerns descriptor admission errors, not schema-free interpretation candidates. This report is AI-assisted and has no post-draft re-verification pass.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: An executed public CLI comparison omits a valid nested-message interpretation while its standalone control successfully decodes the identical group payload. The defect is bounded to candidate classification and leaves original bytes intact.
  • Workaround status: available
  • Workaround basis: The executed standalone raw-body control exposed the group structure for the identical payload; users can extract that retained range for separate inspection, with additional manual work.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6576 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Evidence, artifacts, or reconstruction ## Observed behavior The public `inspect-web-network-capture` CLI decodes `13 18 01 14` as a complete protobuf message: field 2 is a group containing varint field 3 with value 1. Putting those same four bytes inside a length-delimited field (`0a 04 13 18 01 14`) removes `nested-message` from that field's interpretation candidates. The returned alternatives include UTF-8, packed varint, packed fixed32 and bytes, but omit the valid nested-message reading. Both bodies report complete decoding. An ordinary nested message (`0a 02 18 01`) retains the `nested-message` candidate. These three cases ran together through the public CLI once, before drafting. This is a static capture-analysis issue; no server or captured application ran. ## Reproduction Use the audited source checkout with its locked dependencies and built runtime. The executed fixture generator used the repository's inert HAR fixture helper: ```typescript import { writeFile } from 'node:fs/promises'; import { protobufHar } from './tests/fixtures/protobufCapture.ts'; await writeFile('nested-group.har', protobufHar( Buffer.from('13180114', 'hex'), 'application/x-protobuf', [Buffer.from('0a0413180114', 'hex'), Buffer.from('0a021801', 'hex')], )); ``` The imports/output above are expressed relative to the checkout for portability; the executed generator lived outside the checkout and used absolute paths to the same fixture helper and HAR output. Run it with the locked `tsx`, then inspect the three entries: ```sh node scripts/rea.mjs inspect-web-network-capture "$PWD/nested-group.har" har --record 0 --record 1 --record 2 --format json ``` The executed CLI used an absolute temporary HAR path and Node 24.22.1. In `normalized_result.records`, compare each body's `protobuf[0].fields` and `status`. A smaller production wire-decoder probe also observed the missing candidate before this CLI check; it was not a post-draft rerun. ## Expected behavior A length-delimited payload that is a syntactically valid supported protobuf message should retain `nested-message` among its possible interpretations, including when it contains a valid proto2 group. Keep the alternatives ambiguous; do not claim a schema or recursively expand the candidate. The [documented capture contract](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/docs/web-network-captures.md#L134-L145) describes group support and length-delimited nested-message candidates. The executed standalone-body control establishes that this exact group payload is already supported by the wire decoder. ## Impact and scope P2: the interpretation list omits a valid structural reading for length-delimited messages containing groups, which can misdirect schema-free analysis. Original payload bytes and ranges remain intact. The observed scope is the three synthetic HAR records on Linux; no evidence loss or target execution occurred. NOT_ENOUGH_INFO: prevalence in real captures and other producer formats. A bounded workaround is to copy the retained payload bytes into a separate raw protobuf capture body: the standalone control decoded those exact bytes and exposed the group and child. This requires manual extraction; it does not repair the original interpretation list. ## REA version Main source `46111dd091f2ae01baab9eb119b53b9bd309a05b`, package metadata `6.7.0`. This is a main-only finding. The audited protobuf implementation does not exist at the latest published `rea-agents-6.7.0` tag (`27dc42d10249f0410904a75c0997842eb03b931c`); no published-package failure is claimed. ## Runtime and platform Node.js v24.22.1 for the public CLI; Linux x86_64. Dependencies and source build used the repository-pinned Node/npm versions. The smaller wire probe used supported Node.js v26.12.1. No external capture provider was invoked. ## Target and artifact context An inert three-entry HAR with base64 response bodies, MIME type `application/x-protobuf`, and the exact protobuf bytes above. URLs use `example.invalid`; no private target data. ## Interface CLI ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence Reduced from the executed public CLI result: ```json [ {"ordinal":0,"status":"complete","fields":[{"number":2,"wire_type":"group","parent_index":null},{"number":3,"wire_type":"varint","parent_index":0}]}, {"ordinal":1,"status":"complete","fields":[{"number":1,"wire_type":"len","parent_index":null,"interpretations":["utf8-string","packed-varint","packed-fixed32","bytes"]}]}, {"ordinal":2,"status":"complete","fields":[{"number":1,"wire_type":"len","parent_index":null,"interpretations":["utf8-string","nested-message","packed-varint","bytes"]}]} ] ``` All three selected records also received `protobuf_coverage.status: "complete"`. Complete wire coverage is not itself the bug; the missing valid interpretation in record 1 is the discrepancy. ## Typed outcome or recovery expected Record 1 should include `nested-message` without dropping its other valid candidates. Malformed or mismatched groups should continue to fail the candidate check. ## Analysis or suspected cause Source-derived: [`messageCandidate`](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/browser/history/protobuf/ProtobufWire.ts#L50-L85) accepts wire types 0, 1, 2 and 5, returning false for every group start. The [full decoder](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/browser/history/protobuf/ProtobufWire.ts#L181-L189) supports groups. These two syntax interpretations disagree on the same bytes. ## Additional context Searched the supplied open-issue inventory and all-state GitHub issue searches for `protobuf` and `protobuf group`. No matching report was found. Open #6118 concerns descriptor admission errors, not schema-free interpretation candidates. This report is AI-assisted and has no post-draft re-verification pass. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: An executed public CLI comparison omits a valid nested-message interpretation while its standalone control successfully decodes the identical group payload. The defect is bounded to candidate classification and leaves original bytes intact. - Workaround status: available - Workaround basis: The executed standalone raw-body control exposed the group structure for the identical payload; users can extract that retained range for separate inspection, with additional manual work.
Author
Owner

@morluto commented on GitHub (Oct 23, 2026):

Fixed on main in github.com/morluto/rea@b3c3b21e43. Nested-message candidate discovery shares the wire grammar and retains supported matched proto2 groups.

Validation: src/browser/history/protobuf/ProtobufWire.test.ts passed in the retained audit receipt. Direct and wrapped group grammar parity, including mismatched, missing and stray end-group controls.

Scope: Controlled production module tests; original external-provider/public-adapter replay was not rerun. Closure is scoped to this deterministic owning-boundary defect, not general provider qualification.

<!-- gh-comment-id:6376016249 --> @morluto commented on GitHub (Oct 23, 2026): Fixed on main in https://github.com/morluto/rea/commit/b3c3b21e43cab4e71b460d08829d8c6e4e9b9c21. Nested-message candidate discovery shares the wire grammar and retains supported matched proto2 groups. Validation: `src/browser/history/protobuf/ProtobufWire.test.ts` passed in the retained audit receipt. Direct and wrapped group grammar parity, including mismatched, missing and stray end-group controls. Scope: Controlled production module tests; original external-provider/public-adapter replay was not rerun. Closure is scoped to this deterministic owning-boundary defect, not general provider qualification.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3966
No description provided.