[GH-ISSUE #4622] [Bug] Go input-size refusal recommends increasing an evidence-reply allowance #2401

Closed
opened 2026-10-17 21:04:11 +00:00 by bsakaguchi · 2 comments
Owner

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

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-go-binary correctly rejects a selected file over its fixed 256 MiB input limit as resource_constraint, resource file-size, with retryable: false and maximum_input_bytes: 268435456. Its recovery action instead tells callers to review a worker write failure and increase the file-size allowance for an evidence reply. This failure occurs before reading or parsing the selected file, with no evidence-reply write failure involved. The stated recovery addresses a different boundary and cannot change this fixed input allowance.

An ordinary small Go binary inspected successfully on both tested builds. An oversized copy of that binary reproduced the misleading action in 3/3 calls per build. No selected binary was executed.

Reproduction

  1. Obtain either tested build. Install the release in a disposable directory, or install locked source dependencies and run npm run build:cached. Set aside an ordinary small Go binary. The tested control was built from package main; func main() {} with CGO_ENABLED=0, using go build -o small-go main.go.
  2. Save the following as reproduce.py in a disposable directory. Run python3 reproduce.py /absolute/path/to/build/scripts/rea.mjs /absolute/path/to/small-go against each build. It copies the selected binary, sparsely extends the copy to one byte above the input limit, and isolates HOME/config/cache/runtime per call. Padding is a size-admission fixture; successful parsing of the oversized copy is not claimed.
import json, os, pathlib, shutil, subprocess, sys, tempfile
entry, small = map(lambda p: pathlib.Path(p).resolve(), sys.argv[1:3])
root = pathlib.Path(tempfile.mkdtemp(dir=pathlib.Path.cwd()))
try:
    oversized = root / 'oversized-go'
    shutil.copyfile(small, oversized)
    with oversized.open('r+b') as f:
        f.truncate(268435457)
    for index, selected in enumerate([small, oversized, oversized, oversized]):
        case = root / str(index)
        case.mkdir()
        for part in ['home', 'runtime', 'config', 'cache']:
            (case / part).mkdir()
        env = {'PATH': os.environ['PATH'], 'HOME': str(case / 'home'),
               'TMPDIR': str(case / 'runtime'), 'XDG_RUNTIME_DIR': str(case / 'runtime'),
               'XDG_CONFIG_HOME': str(case / 'config'), 'XDG_CACHE_HOME': str(case / 'cache'),
               'REA_LOG_LEVEL': 'silent', 'LANG': 'C'}
        r = subprocess.run([shutil.which('node'), str(entry), 'inspect-go-binary', str(selected), '--format', 'json'],
                           env=env, capture_output=True, text=True, timeout=90)
        reply = json.loads(r.stdout)
        summary = {'case': 'small' if index == 0 else 'oversized', 'exit': r.returncode,
                   'code': reply.get('code'), 'category': reply.get('category'),
                   'retryable': reply.get('retryable'), 'remediation': reply.get('remediation'),
                   'details': reply.get('details'), 'normalized_result': reply.get('normalized_result') if index == 0 else None}
        print(json.dumps(summary).replace(str(root), '<fixture>').replace(str(small), '<fixture>/small-go'), flush=True)
        assert r.stderr == ''
        assert list((case / 'runtime').iterdir()) == []
        assert r.returncode == (0 if index == 0 else 1)
        if index > 0:
            assert reply['code'] == 'resource_constraint'
            assert reply['details']['resource'] == 'file-size'
finally:
    shutil.rmtree(root)
  1. Observe the small control exit 0. All oversized calls exit 1 with the input limit in details, but the action quoted below refers to output writes and an evidence-reply allowance.

Expected behavior

Preserve the input-size refusal, resource classification, fixed byte limit and nonretryable status. Recovery guidance should explain that the selected artifact exceeds the supported input allowance and direct the caller to a suitable input within that allowance, without implying that raising output-write or evidence-reply limits can admit this file. The Go guide documents a selected-file bound of 256 MiB separately from the normalized-report and MCP transport budgets. The provider passes that fixed input bound to the stable reader before format parsing.

Impact and scope

Callers following remediation.action are directed toward a write-limit adjustment that cannot resolve the actual fixed input-limit refusal. The limit remains enforced and the accurate reason and maximum_input_bytes remain available in details, so callers can work around the bad action by inspecting those fields. No data loss, limit bypass, actual write failure, or downstream client incident was observed. This report covers the public CLI selected-input size path; MCP, other providers, and genuine output-write-limit failures were not exercised. Workload prevalence is unknown.

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A bounded supported refusal gives recovery guidance for the wrong resource boundary, directing callers toward a change that cannot resolve this input condition.
  • Workaround status: available
  • Workaround basis: Use the retained input-size reason and structured maximum to recognize the refusal separately from the action. The small original Go binary inspected successfully on both builds. Do not truncate required binary bytes or discard required evidence merely to fit the allowance.

REA version

Published npm rea-agents 6.5.0, and current main source commit 0c7b6d834af2d044b23196e0e522cc2468327a1e, freshly cloned and built locally. Both CLI entrypoints report 6.5.0.

Runtime and platform

Node.js v26.12.0; Darwin arm64. The 1831778-byte control is a Mach-O arm64 Go executable built with Go go1.27.1 and CGO_ENABLED=0. Source build used npm 11.16.0 and this supported Node runtime rather than the preferred development Node version. Go is used only to prepare the control; REA's static inspection launches no Go compiler.

Target and artifact context

A self-generated small Go executable and its sparsely extended 268435457-byte copy. The oversized copy is refused at size admission before content parsing. The original succeeds with retained Go build information. The copy is never executed and the original is not modified.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

  • Expected source: docs/go-binaries.md:88-104 distinguishes selected-input and report/transport bounds; src/go/GoBinaryProvider.ts:46,79-87,213-223 fixes the input allowance and reads before parsing.
  • Failure source: The public CLI results below, and src/domain/analysisErrorPresentation.ts:61-72, whose generic file-size action describes worker output writes.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Meaningful output from each oversized call on both builds (generated path prefix replaced with <fixture>):

{
  "code": "resource_constraint",
  "category": "resource_constraint",
  "retryable": false,
  "remediation": {
    "action": "Review the reported worker file-size limits and write failure. Retry with a sufficient file-size allowance for the evidence reply; REA retains tighter inherited limits."
  },
  "details": {
    "operation": "inspect_go_binary",
    "resource": "file-size",
    "reason": "Selected artifact exceeds 268435456 bytes: <fixture>/oversized-go",
    "reported_limits": { "maximum_input_bytes": 268435456 }
  }
}

Each oversized call exited 1; both small controls exited 0 and returned normalized Go build information. All CLI stderr was empty, and each per-call runtime directory was empty afterward. The embedded reproduction was replayed against both builds.

Typed outcome or recovery expected

For the same oversized copy, retain resource_constraint, resource file-size, retryable: false, and the configured input maximum, with an action about the selected input exceeding that fixed maximum. The small original must remain inspectable. Preserve truthful output-write recovery for genuine write failures. These are proposed restoration checks; no fix was applied.

Analysis or suspected cause

Source-derived reasoning: the Go provider converts the stable reader's limit failure into a file-size resource constraint without a producer-specific action. The shared presentation then selects its fallback for worker evidence-reply writes. The correct resource kind is already present; the error needs recovery semantics matching its input-admission context. This does not prescribe where maintainers should implement that distinction.

Additional context

Related #4192 concerned PE input refusals being labeled as memory constraints. Its body mentions that the generic file-size fallback would still describe output writes, but its trigger and restoration criteria concern the PE provider. This report reproduces the separate Go selected-input path with an already correct file-size classification. Open and closed issues and PRs were searched for Go size/recovery/remediation, worker file-size wording and the exact evidence-reply allowance phrase; no matching Go report or last-known-good revision was found.

Originally created by @coygeek on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4622 ### 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-go-binary` correctly rejects a selected file over its fixed 256 MiB input limit as `resource_constraint`, resource `file-size`, with `retryable: false` and `maximum_input_bytes: 268435456`. Its recovery action instead tells callers to review a worker write failure and increase the file-size allowance for an evidence reply. This failure occurs before reading or parsing the selected file, with no evidence-reply write failure involved. The stated recovery addresses a different boundary and cannot change this fixed input allowance. An ordinary small Go binary inspected successfully on both tested builds. An oversized copy of that binary reproduced the misleading action in 3/3 calls per build. No selected binary was executed. ### Reproduction 1. Obtain either tested build. Install the release in a disposable directory, or install locked source dependencies and run `npm run build:cached`. Set aside an ordinary small Go binary. The tested control was built from `package main; func main() {}` with `CGO_ENABLED=0`, using `go build -o small-go main.go`. 2. Save the following as `reproduce.py` in a disposable directory. Run `python3 reproduce.py /absolute/path/to/build/scripts/rea.mjs /absolute/path/to/small-go` against each build. It copies the selected binary, sparsely extends the copy to one byte above the input limit, and isolates HOME/config/cache/runtime per call. Padding is a size-admission fixture; successful parsing of the oversized copy is not claimed. ```python import json, os, pathlib, shutil, subprocess, sys, tempfile entry, small = map(lambda p: pathlib.Path(p).resolve(), sys.argv[1:3]) root = pathlib.Path(tempfile.mkdtemp(dir=pathlib.Path.cwd())) try: oversized = root / 'oversized-go' shutil.copyfile(small, oversized) with oversized.open('r+b') as f: f.truncate(268435457) for index, selected in enumerate([small, oversized, oversized, oversized]): case = root / str(index) case.mkdir() for part in ['home', 'runtime', 'config', 'cache']: (case / part).mkdir() env = {'PATH': os.environ['PATH'], 'HOME': str(case / 'home'), 'TMPDIR': str(case / 'runtime'), 'XDG_RUNTIME_DIR': str(case / 'runtime'), 'XDG_CONFIG_HOME': str(case / 'config'), 'XDG_CACHE_HOME': str(case / 'cache'), 'REA_LOG_LEVEL': 'silent', 'LANG': 'C'} r = subprocess.run([shutil.which('node'), str(entry), 'inspect-go-binary', str(selected), '--format', 'json'], env=env, capture_output=True, text=True, timeout=90) reply = json.loads(r.stdout) summary = {'case': 'small' if index == 0 else 'oversized', 'exit': r.returncode, 'code': reply.get('code'), 'category': reply.get('category'), 'retryable': reply.get('retryable'), 'remediation': reply.get('remediation'), 'details': reply.get('details'), 'normalized_result': reply.get('normalized_result') if index == 0 else None} print(json.dumps(summary).replace(str(root), '<fixture>').replace(str(small), '<fixture>/small-go'), flush=True) assert r.stderr == '' assert list((case / 'runtime').iterdir()) == [] assert r.returncode == (0 if index == 0 else 1) if index > 0: assert reply['code'] == 'resource_constraint' assert reply['details']['resource'] == 'file-size' finally: shutil.rmtree(root) ``` 3. Observe the small control exit 0. All oversized calls exit 1 with the input limit in `details`, but the action quoted below refers to output writes and an evidence-reply allowance. ### Expected behavior Preserve the input-size refusal, resource classification, fixed byte limit and nonretryable status. Recovery guidance should explain that the selected artifact exceeds the supported input allowance and direct the caller to a suitable input within that allowance, without implying that raising output-write or evidence-reply limits can admit this file. The Go guide documents a selected-file bound of 256 MiB separately from the normalized-report and MCP transport budgets. The provider passes that fixed input bound to the stable reader before format parsing. ### Impact and scope Callers following `remediation.action` are directed toward a write-limit adjustment that cannot resolve the actual fixed input-limit refusal. The limit remains enforced and the accurate reason and `maximum_input_bytes` remain available in `details`, so callers can work around the bad action by inspecting those fields. No data loss, limit bypass, actual write failure, or downstream client incident was observed. This report covers the public CLI selected-input size path; MCP, other providers, and genuine output-write-limit failures were not exercised. Workload prevalence is unknown. - Impact level: P2 - Assessment status: supported - Impact basis: A bounded supported refusal gives recovery guidance for the wrong resource boundary, directing callers toward a change that cannot resolve this input condition. - Workaround status: available - Workaround basis: Use the retained input-size reason and structured maximum to recognize the refusal separately from the action. The small original Go binary inspected successfully on both builds. Do not truncate required binary bytes or discard required evidence merely to fit the allowance. ### REA version Published npm `rea-agents` 6.5.0, and current main source commit `0c7b6d834af2d044b23196e0e522cc2468327a1e`, freshly cloned and built locally. Both CLI entrypoints report `6.5.0`. ### Runtime and platform Node.js v26.12.0; Darwin arm64. The 1831778-byte control is a Mach-O arm64 Go executable built with Go go1.27.1 and `CGO_ENABLED=0`. Source build used npm 11.16.0 and this supported Node runtime rather than the preferred development Node version. Go is used only to prepare the control; REA's static inspection launches no Go compiler. ### Target and artifact context A self-generated small Go executable and its sparsely extended 268435457-byte copy. The oversized copy is refused at size admission before content parsing. The original succeeds with retained Go build information. The copy is never executed and the original is not modified. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence - Expected source: `docs/go-binaries.md:88-104` distinguishes selected-input and report/transport bounds; `src/go/GoBinaryProvider.ts:46,79-87,213-223` fixes the input allowance and reads before parsing. - Failure source: The public CLI results below, and `src/domain/analysisErrorPresentation.ts:61-72`, whose generic `file-size` action describes worker output writes. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Meaningful output from each oversized call on both builds (generated path prefix replaced with `<fixture>`): ```json { "code": "resource_constraint", "category": "resource_constraint", "retryable": false, "remediation": { "action": "Review the reported worker file-size limits and write failure. Retry with a sufficient file-size allowance for the evidence reply; REA retains tighter inherited limits." }, "details": { "operation": "inspect_go_binary", "resource": "file-size", "reason": "Selected artifact exceeds 268435456 bytes: <fixture>/oversized-go", "reported_limits": { "maximum_input_bytes": 268435456 } } } ``` Each oversized call exited 1; both small controls exited 0 and returned normalized Go build information. All CLI stderr was empty, and each per-call runtime directory was empty afterward. The embedded reproduction was replayed against both builds. ### Typed outcome or recovery expected For the same oversized copy, retain `resource_constraint`, resource `file-size`, `retryable: false`, and the configured input maximum, with an action about the selected input exceeding that fixed maximum. The small original must remain inspectable. Preserve truthful output-write recovery for genuine write failures. These are proposed restoration checks; no fix was applied. ### Analysis or suspected cause Source-derived reasoning: the Go provider converts the stable reader's `limit` failure into a file-size resource constraint without a producer-specific action. The shared presentation then selects its fallback for worker evidence-reply writes. The correct resource kind is already present; the error needs recovery semantics matching its input-admission context. This does not prescribe where maintainers should implement that distinction. ### Additional context Related [#4192](https://github.com/morluto/rea/issues/4192) concerned PE input refusals being labeled as memory constraints. Its body mentions that the generic file-size fallback would still describe output writes, but its trigger and restoration criteria concern the PE provider. This report reproduces the separate Go selected-input path with an already correct file-size classification. Open and closed issues and PRs were searched for Go size/recovery/remediation, worker file-size wording and the exact evidence-reply allowance phrase; no matching Go report or last-known-good revision was found.
Author
Owner

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

Addressed in 8451d2839. Go input-size recovery now concerns the selected artifact rather than evidence-reply writes.

The producing reader's file-size boundary stays distinct from configuration admission and producer-output limits. WABT artifact input-size failures now project as resource_constraint, resource file-size, retryable: false, with reported_limits.maximum_input_bytes. Go retains that classification and now supplies recovery for its fixed selected-input allowance. Generic evidence-write recovery is unchanged. Independent cleanup failure remains visible rather than being hidden.

Validation: 66 focused tests across four files passed, including public CLI sparse oversized-input refusals, Go provider controls, WABT configuration/cleanup controls, and shared error projections. Docs checks plus five conformance tests passed. The immediate-parent compiled CLI comparison independently reproduced WABT's old invalid-input response and Go's old evidence-reply recovery. WABT commands were version-only stubs; the sparse inputs were refused before content parsing. No real WABT, valid over-limit WASM, physical/native target behavior, or full CI result is claimed in this local validation.

Bounded completed CLI comparison (two alternating warm repeats/build plus separate first processes): Go baseline/candidate elapsed 0.35167/0.34207 s, CPU 0.52354/0.52181 s, sampled process-family RSS 336994304/342949888 bytes, reply tokens 152/150; WASM elapsed 0.80142/0.81300 s, CPU 1.08851/1.07869 s, RSS 519667712/518176768 bytes, tokens 104/152. Raw tokens use cl100k_base. Reply changes are intentional; no speed/token improvement is established. True cold, whole-agent/schema/request/retry and real-producer costs remain unmeasured. Heavy Qodo tests remained stopped.

<!-- gh-comment-id:6227533778 --> @morluto commented on GitHub (Oct 17, 2026): Addressed in `8451d2839`. Go input-size recovery now concerns the selected artifact rather than evidence-reply writes. The producing reader's file-size boundary stays distinct from configuration admission and producer-output limits. WABT artifact input-size failures now project as `resource_constraint`, resource `file-size`, `retryable: false`, with `reported_limits.maximum_input_bytes`. Go retains that classification and now supplies recovery for its fixed selected-input allowance. Generic evidence-write recovery is unchanged. Independent cleanup failure remains visible rather than being hidden. Validation: 66 focused tests across four files passed, including public CLI sparse oversized-input refusals, Go provider controls, WABT configuration/cleanup controls, and shared error projections. Docs checks plus five conformance tests passed. The immediate-parent compiled CLI comparison independently reproduced WABT's old invalid-input response and Go's old evidence-reply recovery. WABT commands were version-only stubs; the sparse inputs were refused before content parsing. No real WABT, valid over-limit WASM, physical/native target behavior, or full CI result is claimed in this local validation. Bounded completed CLI comparison (two alternating warm repeats/build plus separate first processes): Go baseline/candidate elapsed 0.35167/0.34207 s, CPU 0.52354/0.52181 s, sampled process-family RSS 336994304/342949888 bytes, reply tokens 152/150; WASM elapsed 0.80142/0.81300 s, CPU 1.08851/1.07869 s, RSS 519667712/518176768 bytes, tokens 104/152. Raw tokens use cl100k_base. Reply changes are intentional; no speed/token improvement is established. True cold, whole-agent/schema/request/retry and real-producer costs remain unmeasured. Heavy Qodo tests remained stopped.
Author
Owner

@coygeek commented on GitHub (Oct 18, 2026):

Closing as addressed on main by 8451d2839. Go input-size refusal now gives recovery guidance about selecting a stable input within the fixed allowance, preserving file-size resource metadata and leaving genuine evidence-write recovery separate. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.

<!-- gh-comment-id:6244114636 --> @coygeek commented on GitHub (Oct 18, 2026): Closing as addressed on `main` by [8451d2839](https://github.com/morluto/rea/commit/8451d283920e86936576fdf67615807d1b4ca4a9). Go input-size refusal now gives recovery guidance about selecting a stable input within the fixed allowance, preserving file-size resource metadata and leaving genuine evidence-write recovery separate. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.
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#2401
No description provided.