[GH-ISSUE #6639] [Bug] WASM glue drops valid URL literals with line separators in queries or fragments #4021

Closed
opened 2026-10-31 00:46:08 +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/6639

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

WASM glue analysis reports parse_status: "complete" but omits static URL literals whose query or fragment contains U+2028, U+2029, or an escaped newline. An ordinary query-string control is retained. All four strings are valid JavaScript literals and new URL(value).pathname is /empty.wasm for each.

Observed through the real source WasmArtifactService.inspect with the unchanged WABT 1.0.42 tools and a valid empty core module: inspection succeeds with validation: "valid", but the selected glue has only one reference instead of four. No glue or WASM code was executed and no URL was fetched. Public CLI/MCP adapters were not separately exercised.

Reproduction

From the source checkout with dependencies installed, save the following as a scratch repro-glue.mjs and run node /tmp/rea-wasm-probe/repro-glue.mjs. This is the reduced adapter probe actually executed; the loader only resolves source .js imports to their .ts files for Node's native type stripping.

import { registerHooks } from 'node:module';
import { existsSync } from 'node:fs';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { resolve } from 'node:path';
registerHooks({ resolve(specifier, context, next) {
  try { return next(specifier, context); } catch (error) {
    if (error.code === 'ERR_MODULE_NOT_FOUND' && /^\.{1,2}\//.test(specifier) && specifier.endsWith('.js')) {
      const url = new URL(specifier.slice(0, -3) + '.ts', context.parentURL);
      if (existsSync(fileURLToPath(url))) return next(url.href, context);
    }
    throw error;
  }
}});
const { associateWasmGlue } = await import(pathToFileURL(resolve('src/wasm/WasmGlueAdapter.ts')).href);
const urls = [
  'https://example.invalid/empty.wasm?x=a',
  'https://example.invalid/empty.wasm?x=\u2028',
  'https://example.invalid/empty.wasm#x=\u2029',
  'https://example.invalid/empty.wasm?x=a\nb',
];
const source = urls.map(value => `fetch(${JSON.stringify(value)});`).join('\n');
new Function(source); // Parse only: do not execute the glue.
console.log(JSON.stringify({ validJavaScript: true, urlPathnames: urls.map(value => new URL(value).pathname) }));
console.log(JSON.stringify(associateWasmGlue(source, '/artifacts/glue.mjs', ['/artifacts/empty.wasm'])));

The four-input adapter probe and a source service inspection were each executed successfully. No frequency beyond these probes is established.

Expected behavior

Retain all four static literals, their exact values and source coordinates, with /artifacts/empty.wasm as a basename candidate in the reduced probe. Do not require a query or fragment to fit on one decoded line.

The glue contract says .wasm string literals and URL query/fragment variants are retained as literal associations. These fixtures use ordinary string literals, not computed expressions or aliases.

Impact and scope

Three of the four tested reference occurrences disappear from automatic glue metadata while parsing reports success. The affected values contain a line separator after ? or #; ordinary one-line query strings work. U+2028 and U+2029 are percent-encoded by URL parsing, and the newline is removed from the parsed query, without changing the .wasm pathname.

Original selected files remain unchanged and can be read manually. Real-world frequency, other separators, other platforms and public CLI/MCP projection are untested.

REA version

Source revision a281455f0b83c088ea30ebbb887398888ed167fb on main; package version 6.7.0. This is an unreleased source checkout, not a reproduction of the separately published rea-agents-6.7.0 tag.

Runtime and platform

Node.js v26.12.1; Linux x86_64. The service probe used official WABT 1.0.42 Linux x64 executables. No native-analysis provider was used.

Target and artifact context

A synthetic valid empty core WASM module and a selected .mjs glue file with four ordinary fetch(...) string-literal arguments. fetch was never called. The reduced adapter probe uses generic candidate paths and requires no module file.

Interface

Other

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Reduced probe output:

{"validJavaScript":true,"urlPathnames":["/empty.wasm","/empty.wasm","/empty.wasm","/empty.wasm"]}
{"parse_status":"complete","references":[{"value":"https://example.invalid/empty.wasm?x=a","line":1,"column":6,"candidate_paths":["/artifacts/empty.wasm"],"association":"basename-candidates","evidence_kind":"static-literal"}]}

The real source service returned ok: true, validation: "valid" and the same single reference in its selected glue record. That probe loaded unmodified source with an on-demand TypeScript 6 transpile hook and launched only WABT's validator/objdump/decoder. The reduced probe above uses native Node type stripping. No compiled CLI or MCP transport result is claimed.

Typed outcome or recovery expected

A complete parse with four static-literal references, preserving each original value and its basename association. No runtime-loading or URL-to-file identity claim is needed.

Analysis or suspected cause

Source-derived: the suffix detector slices the cooked literal after its last line separator before testing the .wasm suffix. A separator in the optional query or fragment therefore discards the pathname before the test. The visitor returns before recording those valid literals. This explains the observed omissions; no fix was implemented.

Additional context

Open and closed searches covered "wasm" "query", "wasm" "separator", and WASM literal/line title terms. Related reports #4001 (directive literals), #4474 (JavaScript parser selection), #6588 (source-phase import syntax), and #3402 (equivalent candidate paths) concern different producing conditions. No last-known-good version was established.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The executed adapter and real source service omit three valid static references from a four-reference input while reporting complete parsing. The observed defect is bounded metadata loss; no target execution or file modification occurred.
  • Workaround status: available
  • Workaround basis: The selected glue source remains unchanged, and the probe's printed source and URL list expose all four literal values for manual recovery. This does not restore automatic reference collection.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6639 ### 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 WASM glue analysis reports `parse_status: "complete"` but omits static URL literals whose query or fragment contains U+2028, U+2029, or an escaped newline. An ordinary query-string control is retained. All four strings are valid JavaScript literals and `new URL(value).pathname` is `/empty.wasm` for each. Observed through the real source `WasmArtifactService.inspect` with the unchanged WABT 1.0.42 tools and a valid empty core module: inspection succeeds with `validation: "valid"`, but the selected glue has only one reference instead of four. No glue or WASM code was executed and no URL was fetched. Public CLI/MCP adapters were not separately exercised. ### Reproduction From the source checkout with dependencies installed, save the following as a scratch `repro-glue.mjs` and run `node /tmp/rea-wasm-probe/repro-glue.mjs`. This is the reduced adapter probe actually executed; the loader only resolves source `.js` imports to their `.ts` files for Node's native type stripping. ```js import { registerHooks } from 'node:module'; import { existsSync } from 'node:fs'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { resolve } from 'node:path'; registerHooks({ resolve(specifier, context, next) { try { return next(specifier, context); } catch (error) { if (error.code === 'ERR_MODULE_NOT_FOUND' && /^\.{1,2}\//.test(specifier) && specifier.endsWith('.js')) { const url = new URL(specifier.slice(0, -3) + '.ts', context.parentURL); if (existsSync(fileURLToPath(url))) return next(url.href, context); } throw error; } }}); const { associateWasmGlue } = await import(pathToFileURL(resolve('src/wasm/WasmGlueAdapter.ts')).href); const urls = [ 'https://example.invalid/empty.wasm?x=a', 'https://example.invalid/empty.wasm?x=\u2028', 'https://example.invalid/empty.wasm#x=\u2029', 'https://example.invalid/empty.wasm?x=a\nb', ]; const source = urls.map(value => `fetch(${JSON.stringify(value)});`).join('\n'); new Function(source); // Parse only: do not execute the glue. console.log(JSON.stringify({ validJavaScript: true, urlPathnames: urls.map(value => new URL(value).pathname) })); console.log(JSON.stringify(associateWasmGlue(source, '/artifacts/glue.mjs', ['/artifacts/empty.wasm']))); ``` The four-input adapter probe and a source service inspection were each executed successfully. No frequency beyond these probes is established. ### Expected behavior Retain all four static literals, their exact values and source coordinates, with `/artifacts/empty.wasm` as a basename candidate in the reduced probe. Do not require a query or fragment to fit on one decoded line. The [glue contract](https://github.com/morluto/rea/blob/a281455f0b83c088ea30ebbb887398888ed167fb/docs/wasm-artifacts.md#L123-L130) says `.wasm` string literals and URL query/fragment variants are retained as literal associations. These fixtures use ordinary string literals, not computed expressions or aliases. ### Impact and scope Three of the four tested reference occurrences disappear from automatic glue metadata while parsing reports success. The affected values contain a line separator after `?` or `#`; ordinary one-line query strings work. U+2028 and U+2029 are percent-encoded by URL parsing, and the newline is removed from the parsed query, without changing the `.wasm` pathname. Original selected files remain unchanged and can be read manually. Real-world frequency, other separators, other platforms and public CLI/MCP projection are untested. ### REA version Source revision `a281455f0b83c088ea30ebbb887398888ed167fb` on main; package version `6.7.0`. This is an unreleased source checkout, not a reproduction of the separately published `rea-agents-6.7.0` tag. ### Runtime and platform Node.js v26.12.1; Linux x86_64. The service probe used official WABT 1.0.42 Linux x64 executables. No native-analysis provider was used. ### Target and artifact context A synthetic valid empty core WASM module and a selected `.mjs` glue file with four ordinary `fetch(...)` string-literal arguments. `fetch` was never called. The reduced adapter probe uses generic candidate paths and requires no module file. ### Interface Other ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Reduced probe output: ```json {"validJavaScript":true,"urlPathnames":["/empty.wasm","/empty.wasm","/empty.wasm","/empty.wasm"]} {"parse_status":"complete","references":[{"value":"https://example.invalid/empty.wasm?x=a","line":1,"column":6,"candidate_paths":["/artifacts/empty.wasm"],"association":"basename-candidates","evidence_kind":"static-literal"}]} ``` The real source service returned `ok: true`, `validation: "valid"` and the same single reference in its selected glue record. That probe loaded unmodified source with an on-demand TypeScript 6 transpile hook and launched only WABT's validator/objdump/decoder. The reduced probe above uses native Node type stripping. No compiled CLI or MCP transport result is claimed. ### Typed outcome or recovery expected A complete parse with four `static-literal` references, preserving each original value and its basename association. No runtime-loading or URL-to-file identity claim is needed. ### Analysis or suspected cause Source-derived: [the suffix detector](https://github.com/morluto/rea/blob/a281455f0b83c088ea30ebbb887398888ed167fb/src/wasm/WasmGlueAdapter.ts#L7-L22) slices the cooked literal after its last line separator before testing the `.wasm` suffix. A separator in the optional query or fragment therefore discards the pathname before the test. [The visitor](https://github.com/morluto/rea/blob/a281455f0b83c088ea30ebbb887398888ed167fb/src/wasm/WasmGlueAdapter.ts#L54-L68) returns before recording those valid literals. This explains the observed omissions; no fix was implemented. ### Additional context Open and closed searches covered `"wasm" "query"`, `"wasm" "separator"`, and WASM literal/line title terms. Related reports #4001 (directive literals), #4474 (JavaScript parser selection), #6588 (source-phase import syntax), and #3402 (equivalent candidate paths) concern different producing conditions. No last-known-good version was established. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The executed adapter and real source service omit three valid static references from a four-reference input while reporting complete parsing. The observed defect is bounded metadata loss; no target execution or file modification occurred. - Workaround status: available - Workaround basis: The selected glue source remains unchanged, and the probe's printed source and URL list expose all four literal values for manual recovery. This does not restore automatic reference collection.
Author
Owner

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

I am investigating the existing static WASM-glue suffix detector for this report. Planned scope: retain complete cooked literal values and source coordinates when a query/fragment contains line terminators; preserve existing candidate-association semantics and linear handling of hostile long literals. No glue/WASM execution, URL fetching, provider expansion, or target mutation is planned. I will add focused regressions and verify the public boundary where the existing WABT toolchain is available, explicitly recording unavailable local coverage. I checked the complete current issue timeline and public open PR descriptions/file scopes without finding the same fix; this is coordination, not assignment, scope approval, or an exclusive claim. If this is already being handled, please let me know so I can avoid duplicate work.

<!-- gh-comment-id:6367779985 --> @gongfpp commented on GitHub (Oct 23, 2026): I am investigating the existing static WASM-glue suffix detector for this report. Planned scope: retain complete cooked literal values and source coordinates when a query/fragment contains line terminators; preserve existing candidate-association semantics and linear handling of hostile long literals. No glue/WASM execution, URL fetching, provider expansion, or target mutation is planned. I will add focused regressions and verify the public boundary where the existing WABT toolchain is available, explicitly recording unavailable local coverage. I checked the complete current issue timeline and public open PR descriptions/file scopes without finding the same fix; this is coordination, not assignment, scope approval, or an exclusive claim. If this is already being handled, please let me know so I can avoid duplicate work.
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#4021
No description provided.