[GH-ISSUE #6740] [Bug] EVM carrier path-resolution errors are reported as provider execution failures #4104

Closed
opened 2026-10-31 00:46:50 +00:00 by bsakaguchi · 0 comments
Owner

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

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

Runtime-observed at the production EvmInterfaceService / EvmoleInterfaceProvider boundary: selecting a carrier with an overlong filename component (ENAMETOOLONG) or a self-referential directory symlink (ELOOP) returns ProviderAdapterError, projected as execution_failure, and tells the caller to run rea doctor. A missing-path control returns AnalysisInputError / invalid_request with a path issue.

The same result was observed on current main and the separately installed published rea-agents 6.7.0 package. CLI and MCP transports were not exercised.

Reproduction

With the source checkout's locked dependencies installed, save the following driver outside the checkout as /tmp/rea-audit/evm-path-repro.mts. From the checkout run node --import tsx /tmp/rea-audit/evm-path-repro.mts main. To test the published package, set REA_AUDIT_CODE_ROOT to its absolute dist directory and pass release instead. The recorded executions used these same imports, fixture cases and service calls; only scratch directory locations vary. The driver creates a harmless symlink fixture and removes it in finally.

import { mkdtemp, symlink, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { pathToFileURL } from 'node:url';
const target = process.argv[2] ?? 'main';
const code = process.env.REA_AUDIT_CODE_ROOT ?? resolve('src');
const extension = target === 'release' ? 'js' : 'ts';
const load = (p:string) => import(pathToFileURL(`${code}/${p}.${extension}`).href);
const { EvmInterfaceService } = await load('application/evm/EvmInterfaceService');
const { EvmoleInterfaceProvider } = await load('evm/EvmoleInterfaceProvider');
const { projectAnalysisError } = await load('domain/analysisErrorProjection');
const root = await mkdtemp(join(tmpdir(),'rea-evm-path-'));
const service = new EvmInterfaceService(new EvmoleInterfaceProvider());
try {
 await symlink('loop', join(root,'loop'));
 const cases = [
  ['missing-control',join(root,'missing.bin')],
  ['overlong-component',join(root,'x'.repeat(256))],
  ['symlink-loop',join(root,'loop','carrier.bin')],
 ];
 const results=[];
 for(const [label,path] of cases){
  const result=await service.inspect({path,encoding:'raw'});
  results.push(result.ok ? {label,ok:true} : {label,ok:false,tag:result.error._tag,error:projectAnalysisError(result.error)});
 }
 console.log(JSON.stringify({target,node:process.version,platform:process.platform,arch:process.arch,results},null,2));
} finally { await service.close(); await rm(root,{recursive:true,force:true}); }

Each captured main/release run returned the two failures and the successful error-classification control below. No target bytecode or application was executed.

Expected behavior

Classify these selected-path resolution failures as invalid input, retaining an invalid_value issue on path and the filesystem reason. Recovery should ask the caller to correct the selection rather than diagnose the EVM toolchain.

This follows the existing EVM selected-carrier failure mapping, independently observed for the missing-path control. The BEAM reader's corresponding classification explicitly includes ELOOP and ENAMETOOLONG alongside ENOENT and ENOTDIR.

Impact and scope

P2: two bounded local selection errors receive the wrong structured category and recovery action. Clients branching on input/provider errors can diagnose the wrong component. Both failures retain their actual errno in diagnostics, allowing a caller to identify the bad path manually. No data loss, source mutation or successful incorrect bytecode analysis was observed. Real-world frequency and other platforms are untested.

Correcting the selected path is the likely practical recovery, but a successful EVM analysis after changing the path was not tested; workaround availability is therefore unverified.

REA version

Current main bc411c24befceced5a9ea1ca1c1ce123fd02bf48, package version 6.7.0, executed directly from TypeScript source; and the separately installed published npm rea-agents 6.7.0, executed from its packaged JavaScript dist modules.

Runtime and platform

Node.js v26.12.1; Linux x86_64. The runtime satisfies the checkout's supported 26+ line. No Hopper, Ghidra or IDA provider was used.

Target and artifact context

Three explicitly selected local raw EVM carrier paths: a nonexistent file control, a nonexistent path with one 256-byte ASCII filename component, and a file path beneath loop -> loop. No external target data, network request or target execution was involved.

Interface

Other — direct production application/provider boundary and shared projectAnalysisError; CLI/MCP transport remains untested.

Earliest failure stage

Capture or observation

Relevant output or evidence

Observed results from each version:

main    missing-control     AnalysisInputError    invalid_request
main    overlong-component ProviderAdapterError  execution_failure  artifact-read ENAMETOOLONG
main    symlink-loop        ProviderAdapterError  execution_failure  artifact-read ELOOP
release missing-control     AnalysisInputError    invalid_request
release overlong-component ProviderAdapterError  execution_failure  artifact-read ENAMETOOLONG
release symlink-loop        ProviderAdapterError  execution_failure  artifact-read ELOOP

Both path-resolution failures project this recovery action:

Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.

Evidence provenance: observed real filesystem failures and real production service/provider results, followed by the production error projection. No filesystem errors or provider replies were mocked. The source explanation below is separate from the runtime observation. No live CLI/MCP transport result is claimed.

Typed outcome or recovery expected

AnalysisInputError, projected as invalid_request, with path / invalid_value naming ELOOP or ENAMETOOLONG. Retain the original filesystem cause and direct recovery toward a valid readable carrier path. Actual provider, permission, resource and cleanup failures should preserve their existing categories.

Analysis or suspected cause

Source-derived: the carrier read runs in artifact-read before creating the worker runtime. The errno mapping handles permissions and recognizes only ENOENT / ENOTDIR as selected-path failures. ELOOP and ENAMETOOLONG fall through to ProviderAdapterError, producing the observed category and doctor guidance.

Additional context

Open/closed searches for repo:morluto/rea is:issue EVM ENAMETOOLONG and repo:morluto/rea is:issue EVM ELOOP found no exact report. The latter returned tracker #4330; its relevant text does not report this EVM path-error category defect. Related #5949 describes analogous plist behavior in a separate implementation. Closed #5332 concerns EVM artifact-read cancellation reason identity, rather than these filesystem selection errors. Existing EVM reply-budget and inherited-resource reports #5848 and #5087 concern later, independent boundaries.

Last known good release / first bad revision: NOT_ENOUGH_INFO; no regression range was established. Verification finished before this draft was written; the bug was not rerun afterward.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Current main and published 6.7.0 both assign two real local path-resolution errors the provider execution-failure category and doctor recovery, while the missing-path control is correctly attributed to invalid input. The demonstrated consequence is bounded error-contract and recovery misdirection.
  • Workaround status: unverified
  • Workaround basis: The original errno remains visible and correcting the selected path is a plausible recovery, but a successful EVM inspection after that correction was not exercised. The missing-path control establishes error attribution, not a successful analysis workaround.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6740 ## 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 Runtime-observed at the production `EvmInterfaceService` / `EvmoleInterfaceProvider` boundary: selecting a carrier with an overlong filename component (`ENAMETOOLONG`) or a self-referential directory symlink (`ELOOP`) returns `ProviderAdapterError`, projected as `execution_failure`, and tells the caller to run `rea doctor`. A missing-path control returns `AnalysisInputError` / `invalid_request` with a `path` issue. The same result was observed on current main and the separately installed published `rea-agents` 6.7.0 package. CLI and MCP transports were not exercised. ## Reproduction With the source checkout's locked dependencies installed, save the following driver outside the checkout as `/tmp/rea-audit/evm-path-repro.mts`. From the checkout run `node --import tsx /tmp/rea-audit/evm-path-repro.mts main`. To test the published package, set `REA_AUDIT_CODE_ROOT` to its absolute `dist` directory and pass `release` instead. The recorded executions used these same imports, fixture cases and service calls; only scratch directory locations vary. The driver creates a harmless symlink fixture and removes it in `finally`. ```ts import { mkdtemp, symlink, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; const target = process.argv[2] ?? 'main'; const code = process.env.REA_AUDIT_CODE_ROOT ?? resolve('src'); const extension = target === 'release' ? 'js' : 'ts'; const load = (p:string) => import(pathToFileURL(`${code}/${p}.${extension}`).href); const { EvmInterfaceService } = await load('application/evm/EvmInterfaceService'); const { EvmoleInterfaceProvider } = await load('evm/EvmoleInterfaceProvider'); const { projectAnalysisError } = await load('domain/analysisErrorProjection'); const root = await mkdtemp(join(tmpdir(),'rea-evm-path-')); const service = new EvmInterfaceService(new EvmoleInterfaceProvider()); try { await symlink('loop', join(root,'loop')); const cases = [ ['missing-control',join(root,'missing.bin')], ['overlong-component',join(root,'x'.repeat(256))], ['symlink-loop',join(root,'loop','carrier.bin')], ]; const results=[]; for(const [label,path] of cases){ const result=await service.inspect({path,encoding:'raw'}); results.push(result.ok ? {label,ok:true} : {label,ok:false,tag:result.error._tag,error:projectAnalysisError(result.error)}); } console.log(JSON.stringify({target,node:process.version,platform:process.platform,arch:process.arch,results},null,2)); } finally { await service.close(); await rm(root,{recursive:true,force:true}); } ``` Each captured main/release run returned the two failures and the successful error-classification control below. No target bytecode or application was executed. ## Expected behavior Classify these selected-path resolution failures as invalid input, retaining an `invalid_value` issue on `path` and the filesystem reason. Recovery should ask the caller to correct the selection rather than diagnose the EVM toolchain. This follows the existing [EVM selected-carrier failure mapping](https://github.com/morluto/rea/blob/bc411c24befceced5a9ea1ca1c1ce123fd02bf48/src/evm/EvmoleFailures.ts#L207-L226), independently observed for the missing-path control. The [BEAM reader's corresponding classification](https://github.com/morluto/rea/blob/bc411c24befceced5a9ea1ca1c1ce123fd02bf48/src/erlang/BeamProvider.ts#L166-L180) explicitly includes `ELOOP` and `ENAMETOOLONG` alongside `ENOENT` and `ENOTDIR`. ## Impact and scope P2: two bounded local selection errors receive the wrong structured category and recovery action. Clients branching on input/provider errors can diagnose the wrong component. Both failures retain their actual errno in diagnostics, allowing a caller to identify the bad path manually. No data loss, source mutation or successful incorrect bytecode analysis was observed. Real-world frequency and other platforms are untested. Correcting the selected path is the likely practical recovery, but a successful EVM analysis after changing the path was not tested; workaround availability is therefore unverified. ## REA version Current main `bc411c24befceced5a9ea1ca1c1ce123fd02bf48`, package version 6.7.0, executed directly from TypeScript source; and the separately installed published npm `rea-agents` 6.7.0, executed from its packaged JavaScript `dist` modules. ## Runtime and platform Node.js v26.12.1; Linux x86_64. The runtime satisfies the checkout's supported 26+ line. No Hopper, Ghidra or IDA provider was used. ## Target and artifact context Three explicitly selected local raw EVM carrier paths: a nonexistent file control, a nonexistent path with one 256-byte ASCII filename component, and a file path beneath `loop -> loop`. No external target data, network request or target execution was involved. ## Interface Other — direct production application/provider boundary and shared `projectAnalysisError`; CLI/MCP transport remains untested. ## Earliest failure stage Capture or observation ## Relevant output or evidence Observed results from each version: ```text main missing-control AnalysisInputError invalid_request main overlong-component ProviderAdapterError execution_failure artifact-read ENAMETOOLONG main symlink-loop ProviderAdapterError execution_failure artifact-read ELOOP release missing-control AnalysisInputError invalid_request release overlong-component ProviderAdapterError execution_failure artifact-read ENAMETOOLONG release symlink-loop ProviderAdapterError execution_failure artifact-read ELOOP ``` Both path-resolution failures project this recovery action: ```text Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed. ``` Evidence provenance: observed real filesystem failures and real production service/provider results, followed by the production error projection. No filesystem errors or provider replies were mocked. The source explanation below is separate from the runtime observation. No live CLI/MCP transport result is claimed. ## Typed outcome or recovery expected `AnalysisInputError`, projected as `invalid_request`, with `path` / `invalid_value` naming `ELOOP` or `ENAMETOOLONG`. Retain the original filesystem cause and direct recovery toward a valid readable carrier path. Actual provider, permission, resource and cleanup failures should preserve their existing categories. ## Analysis or suspected cause Source-derived: [the carrier read](https://github.com/morluto/rea/blob/bc411c24befceced5a9ea1ca1c1ce123fd02bf48/src/evm/EvmoleInterfaceProvider.ts#L486-L495) runs in `artifact-read` before creating the worker runtime. [The errno mapping](https://github.com/morluto/rea/blob/bc411c24befceced5a9ea1ca1c1ce123fd02bf48/src/evm/EvmoleFailures.ts#L207-L228) handles permissions and recognizes only `ENOENT` / `ENOTDIR` as selected-path failures. `ELOOP` and `ENAMETOOLONG` fall through to `ProviderAdapterError`, producing the observed category and doctor guidance. ## Additional context Open/closed searches for `repo:morluto/rea is:issue EVM ENAMETOOLONG` and `repo:morluto/rea is:issue EVM ELOOP` found no exact report. The latter returned tracker #4330; its relevant text does not report this EVM path-error category defect. Related [#5949](https://github.com/morluto/rea/issues/5949) describes analogous plist behavior in a separate implementation. Closed [#5332](https://github.com/morluto/rea/issues/5332) concerns EVM artifact-read cancellation reason identity, rather than these filesystem selection errors. Existing EVM reply-budget and inherited-resource reports #5848 and #5087 concern later, independent boundaries. Last known good release / first bad revision: NOT_ENOUGH_INFO; no regression range was established. Verification finished before this draft was written; the bug was not rerun afterward. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Current main and published 6.7.0 both assign two real local path-resolution errors the provider execution-failure category and doctor recovery, while the missing-path control is correctly attributed to invalid input. The demonstrated consequence is bounded error-contract and recovery misdirection. - Workaround status: unverified - Workaround basis: The original errno remains visible and correcting the selected path is a plausible recovery, but a successful EVM inspection after that correction was not exercised. The missing-path control establishes error attribution, not a successful analysis workaround.
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#4104
No description provided.