[GH-ISSUE #7297] [Bug] WASM inspection rejects custom-name diagnostics accepted by its validation profile #4334

Closed
opened 2026-10-31 00:48:59 +00:00 by bsakaguchi · 0 comments
Owner

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

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

inspect-wasm-artifact exits 1 with unreadable_output and Unexpected WABT diagnostic output. for a 43-byte module containing a valid exported empty function followed by a custom section with an invalid UTF-8 name. The exact selected WABT validation command exits 0 and REA's retained partial Evidence records validation: "valid". WABT can also dump the sections and decode the complete core module, but labels the unreadable custom name as an error: diagnostic even under the selected tolerant profile. REA treats that diagnostic as unexpected producer output and withholds the complete inspection.

This report does not claim the malformed custom-section name is specification-valid. It concerns the mismatch between the documented selected validation profile, REA's own retained validation result, and the later treatment of an optional-section interpretation diagnostic. The selected byte identity and validation diagnostics are retained in partial Evidence; they are not lost.

Reproduction

From the source checkout with locked dependencies and its built runtime, set REA_WABT_BIN_DIRECTORY to an absolute directory containing WABT 1.0.42. Run in an empty fixture directory; the hex fixture is self-contained and contains no target code other than an empty function. These are the public CLI and producer commands actually executed, with only local paths normalized:

python3 - <<'PY'
from pathlib import Path
core = bytes.fromhex('0061736d0100000001040160000003020100070501016600000a040102000b')
Path('core.wasm').write_bytes(core)
Path('invalid-name.wasm').write_bytes(core + b'\x00\x0a\x02\xff\xfepayload')
Path('opaque-name.wasm').write_bytes(bytes.fromhex('0061736d010000000008046e616d65616263'))
PY
wasm-validate --enable-all --ignore-custom-section-errors invalid-name.wasm
wasm2wat --enable-all --ignore-custom-section-errors invalid-name.wasm
wasm-objdump -h -x invalid-name.wasm
node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/invalid-name.wasm" --format json
node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/core.wasm" --format json
node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/opaque-name.wasm" --format json

Each final CLI case ran once. The malformed-name case failed; both controls succeeded. The readable name section with opaque payload is the exact formerly failing fixture from the related closed metadata report.

Expected behavior

The WASM inspection guide says core validation remains authoritative when an optional custom section cannot be interpreted, and that producer diagnostics are retained as custom_section_warnings. For bytes accepted by the selected tolerant validation profile, retain the available core section/interface inspection and explicitly represent the uninterpretable custom section. The diagnostic should not be attributed to producer format drift with generic rea doctor guidance. If custom-name framing is intentionally outside that recovery contract, its admission and documented typed outcome need to make that boundary explicit rather than recording successful validation followed by an unexpected-output failure.

Impact and scope

P2: a bounded optional-section condition prevents complete normalized inspection of the original bytes, including a supported export interface. The independent fixture fails once while both controls pass. Production prevalence and other platforms are NOT_ENOUGH_INFO; they were not measured. A verified read-only fallback is to run the same three WABT commands directly on the original bytes: all succeed and retain the core export plus the diagnostic. This supplies direct-tool inspection, although it does not produce REA's normalized Evidence. No module was instantiated and no security impact is claimed.

REA version

Executed built source: 0d1a454e25db825567782e461da21530bad4b158, package version 6.8.0. Current main was source-compared: the provider, section reconciler, and cited guide were byte-identical to the executed baseline. Latest published release rea-agents-6.8.0 was source-inspected: it contains the same tolerant validation arguments and diagnostic predicate; its runtime was not executed.

Runtime and platform

Node.js v24.22.1, Darwin 27.0.0 arm64, WABT 1.0.42. The installed WABT version matches its latest published release. Repository-locked dependencies and the prebuilt source runtime were used; no global installation or REA configuration was changed.

Target and artifact context

A self-authored core WebAssembly v1 module exporting f: () -> (), followed by section id 0, payload length 10, declared name length 2, name bytes ff fe, and opaque payload payload. Original artifact length is 43 bytes and SHA-256 is 8b86d518252a9f086a620c9f7585aa587f64b2626aa985aab8985b4f03f0dbae.

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

wasm-validate --enable-all --ignore-custom-section-errors invalid-name.wasm
exit: 0
stderr: 0000024: error: invalid utf-8 encoding: section name

wasm2wat --enable-all --ignore-custom-section-errors invalid-name.wasm
exit: 0
(module
  (type (;0;) (func))
  (func (;0;) (type 0))
  (export "f" (func 0)))

REA CLI, invalid-name.wasm:
exit: 1
code: unreadable_output
category: execution_failure
retryable: false
details.reason: Unexpected WABT diagnostic output.
details.captured_output.exit_code: 0
details.captured_output.stderr: 0000024: error: invalid utf-8 encoding: section name
details.partial_observation.normalized_result.validation: valid

REA CLI, core.wasm:
exit: 0
validation: valid
interface.state: complete
exports: ["(export \"f\" (func 0))"]

REA CLI, opaque-name.wasm:
exit: 0
validation: valid
debug_name_metadata: uninterpretable
custom_section_warnings: retained from all three WABT commands
  • Expected source: docs/wasm-artifacts.md, paragraphs defining the exact --enable-all --ignore-custom-section-errors profile and beginning “Core validation remains authoritative when an optional custom section cannot be interpreted.”
  • Failure source: the executed public CLI output above; src/wasm/WabtArtifactProvider.ts sets validationState = "valid" after the successful producer exit, then retainWarnings accepts only diagnostics matching ^\S+: warning: and throws before objdump/decoding for this fixture.
  • Evidence provenance: observed; independently constructed inert fixtures and executed real WABT and public REA CLI commands. Current-main and published-release persistence statements are separately source-derived.
  • Local verification: reproduced through the built public CLI, including its normal admission, selected-file read, version/digest checks, subprocess supervision, and error projection.
  • Reproduction completeness: complete for the stated CLI fixture and two controls. MCP and the published release runtime were not executed.

Typed outcome or recovery expected

Available core inspection with original byte identity and explicit optional-custom-section limitations/diagnostics under the documented tolerant profile. Preserve unknown custom-name and metadata coverage rather than inventing a decoded name or claiming complete optional metadata.

Analysis or suspected cause

Source-derived: warningOutput distinguishes warning: from every other stderr line, but this selected WABT profile accepts the malformed custom name with exit 0 while printing error:. The subsequent WAT/objdump reconciliation also assumes every custom section has a readable name; correcting only the first diagnostic gate is not established as sufficient. That later reconciliation was not reached by this public CLI request.

Additional context

The related closed metadata case has a readable name section name and an uninterpretable payload; that exact fixture now succeeds as the executed control. The other related closed report concerns an already decoded module name followed by malformed debug-name payload. This report instead concerns the custom section's own unreadable name, an earlier diagnostic gate, and no WAT annotation for that custom section. All-state issue/PR searches found no current open exact duplicate. No REA source was changed. AI assistance: an independent Codex verifier constructed and executed the fixtures, reviewed the source and tracker history, and authored this report.

Restoration check

Run the exact malformed-name fixture and both controls. The malformed-name fixture should retain the available core export and original artifact identity with explicit custom-section limitations instead of Unexpected WABT diagnostic output. Both controls should remain successful, and the opaque name payload must keep its uninterpretable metadata state and producer warnings. Do not make malformed core validation succeed to satisfy this check.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The public inspection CLI withholds complete core inspection for one bounded optional-section condition despite successful selected-profile validation; both controls pass and partial identity/diagnostics remain available.
  • Workaround status: available
  • Workaround basis: The real WABT validator, section dumper, and decoder succeeded on the unchanged original bytes, retaining the core export and diagnostic, although this fallback does not produce normalized REA Evidence.

References

Originally created by @coygeek on GitHub (Oct 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7297 ## 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 `inspect-wasm-artifact` exits 1 with `unreadable_output` and `Unexpected WABT diagnostic output.` for a 43-byte module containing a valid exported empty function followed by a custom section with an invalid UTF-8 name. The exact selected WABT validation command exits 0 and REA's retained partial Evidence records `validation: "valid"`. WABT can also dump the sections and decode the complete core module, but labels the unreadable custom name as an `error:` diagnostic even under the selected tolerant profile. REA treats that diagnostic as unexpected producer output and withholds the complete inspection. This report does not claim the malformed custom-section name is specification-valid. It concerns the mismatch between the documented selected validation profile, REA's own retained validation result, and the later treatment of an optional-section interpretation diagnostic. The selected byte identity and validation diagnostics are retained in partial Evidence; they are not lost. ## Reproduction From the source checkout with locked dependencies and its built runtime, set `REA_WABT_BIN_DIRECTORY` to an absolute directory containing WABT 1.0.42. Run in an empty fixture directory; the hex fixture is self-contained and contains no target code other than an empty function. These are the public CLI and producer commands actually executed, with only local paths normalized: ```sh python3 - <<'PY' from pathlib import Path core = bytes.fromhex('0061736d0100000001040160000003020100070501016600000a040102000b') Path('core.wasm').write_bytes(core) Path('invalid-name.wasm').write_bytes(core + b'\x00\x0a\x02\xff\xfepayload') Path('opaque-name.wasm').write_bytes(bytes.fromhex('0061736d010000000008046e616d65616263')) PY wasm-validate --enable-all --ignore-custom-section-errors invalid-name.wasm wasm2wat --enable-all --ignore-custom-section-errors invalid-name.wasm wasm-objdump -h -x invalid-name.wasm node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/invalid-name.wasm" --format json node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/core.wasm" --format json node /path/to/rea/scripts/rea.mjs inspect-wasm-artifact "$PWD/opaque-name.wasm" --format json ``` Each final CLI case ran once. The malformed-name case failed; both controls succeeded. The readable `name` section with opaque payload is the exact formerly failing fixture from the related closed metadata report. ## Expected behavior The WASM inspection guide says core validation remains authoritative when an optional custom section cannot be interpreted, and that producer diagnostics are retained as `custom_section_warnings`. For bytes accepted by the selected tolerant validation profile, retain the available core section/interface inspection and explicitly represent the uninterpretable custom section. The diagnostic should not be attributed to producer format drift with generic `rea doctor` guidance. If custom-name framing is intentionally outside that recovery contract, its admission and documented typed outcome need to make that boundary explicit rather than recording successful validation followed by an unexpected-output failure. ## Impact and scope P2: a bounded optional-section condition prevents complete normalized inspection of the original bytes, including a supported export interface. The independent fixture fails once while both controls pass. Production prevalence and other platforms are NOT_ENOUGH_INFO; they were not measured. A verified read-only fallback is to run the same three WABT commands directly on the original bytes: all succeed and retain the core export plus the diagnostic. This supplies direct-tool inspection, although it does not produce REA's normalized Evidence. No module was instantiated and no security impact is claimed. ## REA version Executed built source: `0d1a454e25db825567782e461da21530bad4b158`, package version 6.8.0. Current `main` was source-compared: the provider, section reconciler, and cited guide were byte-identical to the executed baseline. Latest published release `rea-agents-6.8.0` was source-inspected: it contains the same tolerant validation arguments and diagnostic predicate; its runtime was not executed. ## Runtime and platform Node.js v24.22.1, Darwin 27.0.0 arm64, WABT 1.0.42. The installed WABT version matches its latest published release. Repository-locked dependencies and the prebuilt source runtime were used; no global installation or REA configuration was changed. ## Target and artifact context A self-authored core WebAssembly v1 module exporting `f: () -> ()`, followed by section id 0, payload length 10, declared name length 2, name bytes `ff fe`, and opaque payload `payload`. Original artifact length is 43 bytes and SHA-256 is `8b86d518252a9f086a620c9f7585aa587f64b2626aa985aab8985b4f03f0dbae`. ## Interface CLI ## Earliest failure stage Capture or observation ## Relevant output or evidence ```text wasm-validate --enable-all --ignore-custom-section-errors invalid-name.wasm exit: 0 stderr: 0000024: error: invalid utf-8 encoding: section name wasm2wat --enable-all --ignore-custom-section-errors invalid-name.wasm exit: 0 (module (type (;0;) (func)) (func (;0;) (type 0)) (export "f" (func 0))) REA CLI, invalid-name.wasm: exit: 1 code: unreadable_output category: execution_failure retryable: false details.reason: Unexpected WABT diagnostic output. details.captured_output.exit_code: 0 details.captured_output.stderr: 0000024: error: invalid utf-8 encoding: section name details.partial_observation.normalized_result.validation: valid REA CLI, core.wasm: exit: 0 validation: valid interface.state: complete exports: ["(export \"f\" (func 0))"] REA CLI, opaque-name.wasm: exit: 0 validation: valid debug_name_metadata: uninterpretable custom_section_warnings: retained from all three WABT commands ``` - Expected source: `docs/wasm-artifacts.md`, paragraphs defining the exact `--enable-all --ignore-custom-section-errors` profile and beginning “Core validation remains authoritative when an optional custom section cannot be interpreted.” - Failure source: the executed public CLI output above; `src/wasm/WabtArtifactProvider.ts` sets `validationState = "valid"` after the successful producer exit, then `retainWarnings` accepts only diagnostics matching `^\S+: warning: ` and throws before objdump/decoding for this fixture. - Evidence provenance: observed; independently constructed inert fixtures and executed real WABT and public REA CLI commands. Current-main and published-release persistence statements are separately source-derived. - Local verification: reproduced through the built public CLI, including its normal admission, selected-file read, version/digest checks, subprocess supervision, and error projection. - Reproduction completeness: complete for the stated CLI fixture and two controls. MCP and the published release runtime were not executed. ## Typed outcome or recovery expected Available core inspection with original byte identity and explicit optional-custom-section limitations/diagnostics under the documented tolerant profile. Preserve unknown custom-name and metadata coverage rather than inventing a decoded name or claiming complete optional metadata. ## Analysis or suspected cause Source-derived: `warningOutput` distinguishes `warning:` from every other stderr line, but this selected WABT profile accepts the malformed custom name with exit 0 while printing `error:`. The subsequent WAT/objdump reconciliation also assumes every custom section has a readable name; correcting only the first diagnostic gate is not established as sufficient. That later reconciliation was not reached by this public CLI request. ## Additional context The related closed metadata case has a readable `name` section name and an uninterpretable payload; that exact fixture now succeeds as the executed control. The other related closed report concerns an already decoded module name followed by malformed debug-name payload. This report instead concerns the custom section's own unreadable name, an earlier diagnostic gate, and no WAT annotation for that custom section. All-state issue/PR searches found no current open exact duplicate. No REA source was changed. AI assistance: an independent Codex verifier constructed and executed the fixtures, reviewed the source and tracker history, and authored this report. ## Restoration check Run the exact malformed-name fixture and both controls. The malformed-name fixture should retain the available core export and original artifact identity with explicit custom-section limitations instead of `Unexpected WABT diagnostic output.` Both controls should remain successful, and the opaque `name` payload must keep its uninterpretable metadata state and producer warnings. Do not make malformed core validation succeed to satisfy this check. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The public inspection CLI withholds complete core inspection for one bounded optional-section condition despite successful selected-profile validation; both controls pass and partial identity/diagnostics remain available. - Workaround status: available - Workaround basis: The real WABT validator, section dumper, and decoder succeeded on the unchanged original bytes, retaining the core export and diagnostic, although this fallback does not produce normalized REA Evidence. ## References - [WASM inspection guide](https://github.com/morluto/rea/blob/main/docs/wasm-artifacts.md). - [Closed optional custom-payload report](https://github.com/morluto/rea/issues/6812): its exact fixture passes as a control; the custom name remains readable. - [Closed partially decoded debug-name framing report](https://github.com/morluto/rea/issues/6885): a different payload/preamble condition after a readable custom name.
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#4334
No description provided.