[GH-ISSUE #7536] [Bug] Amp registration reports success when existing settings prevent saving REA #4477

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

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

Before submitting

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

Area

MCP or agent integration

Observed behavior

node scripts/rea.mjs mcp add --agent amp --command 'node x.mjs' --json exits 0 and announces ✓ Registered rea as MCP server even when the existing Amp settings prevent it from saving a registration.

For a truncated JSON document, the settings remain byte-identical and the returned agents list is empty. For valid JSON containing "amp.mcpServers": [], the command additionally claims Agents: Amp and returns "agents": ["Amp"], but saves the empty array without a rea entry. Both cases have empty stderr and no explanation of the configuration problem.

Reproduction

  1. Use the source revision below, its already installed locked dependencies and compiled runtime, and Node.js v24.22.1 on PATH. Verification used the prepared build; it did not reinstall dependencies or rebuild the checkout.
  2. From the checkout root, run this inline fixture/replay. Each command receives an isolated HOME and XDG configuration, cache, data and state directories. The stored node x.mjs command is not executed by registration.
python3 -I - <<'PY'
import os, pathlib, subprocess, tempfile

fixtures = {
    "malformed": '{ "amp.mcpServers": { "rea": {} ',
    "array": '{"amp.mcpServers": []}\n',
}
with tempfile.TemporaryDirectory() as work:
    for case, fixture in fixtures.items():
        root = pathlib.Path(work) / case
        env = {"PATH": os.environ["PATH"]}
        for key, part in {
            "HOME": "home", "XDG_CONFIG_HOME": "home/.config",
            "XDG_CACHE_HOME": "cache", "XDG_DATA_HOME": "data",
            "XDG_STATE_HOME": "state", "TMPDIR": "tmp",
        }.items():
            directory = root / part
            directory.mkdir(parents=True, exist_ok=True)
            env[key] = str(directory)
        settings = root / "home/.config/amp/settings.json"
        settings.parent.mkdir(parents=True, exist_ok=True)
        settings.write_text(fixture)
        result = subprocess.run(
            ["node", "scripts/rea.mjs", "mcp", "add", "--agent", "amp",
             "--command", "node x.mjs", "--json"],
            env=env, text=True, capture_output=True, timeout=30,
        )
        print(f"{case}: exit={result.returncode}")
        print(result.stdout)
        print(f"stderr={result.stderr!r}")
        print(f"settings={settings.read_text()!r}")
        print(f"unchanged={settings.read_text() == fixture}")
PY
  1. Inspect the printed exit status, success message, agent list and settings bytes. Neither case contains a usable REA registration. Each reproduced in three fresh environments: two initial runs and one replay of this script.

Expected behavior

A registration request should either save the requested server entry or exit nonzero with a diagnostic explaining why registration failed. It should not announce success when no registration was saved, and should not list Amp as registered when its saved settings have no rea entry. Existing malformed settings should remain intact when the operation refuses them.

The command's public help describes it as registering an MCP server. The product explicitly documents this builtin separately from setup; the specific evidence is listed below. This report does not require setup's transactional implementation or a particular new error code.

Impact and scope

P2: the command's success signals conceal an absent registration for the selected client. Callers relying on exit status or the success message receive no registration-failure indication; the array case also misstates the structured agent result. The settings-file contract failure was observed directly. No live Amp client session or subsequent tool lookup was performed.

Valid-object controls saved the expected REA entry twice. Correcting each disposable failing fixture to a valid object and rerunning also saved the entry, demonstrating a repair/rerun workaround. Real settings should be repaired while preserving their unrelated content. Only Amp on the platform below was exercised; other clients, platforms and the frequency of affected real configurations are unknown.

REA version

Exact node scripts/rea.mjs --version stdout:

6.8.0

Source commit: 65f1c447344a423fa2785847dbcea1e9a9e2454a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1 (build 26A434); arm64. The checkout pins Incur 0.6.1. No analysis provider is involved.

Target and artifact context

Two synthetic Amp settings documents: truncated JSON and an empty array in the server-map field. All writes used disposable directories. No analysis target, credentials or real client configuration was used.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

The inline replay above produced the following reduced output; terminal clearing escapes are omitted.

malformed: exit=0
✓ Registered rea as MCP server
Agents can now use rea tools.
{"name":"rea","command":"node x.mjs","agents":[]}
stderr=''
settings='{ "amp.mcpServers": { "rea": {} '
unchanged=True

array: exit=0
✓ Registered rea as MCP server
  Agents: Amp
Agents can now use rea tools.
{"name":"rea","command":"node x.mjs","agents":["Amp"]}
stderr=''
settings='{\n  "amp.mcpServers": []\n}\n'
unchanged=False

Expected-source evidence at the stated revision:

  • Observed node scripts/rea.mjs mcp add --help: rea mcp add — Register as MCP server, with --agent and --command options.
  • docs/installation.md:1100-1109 identifies the separate REA builtin and explains that setup does not replace arbitrary command registrations or unsupported-client registrations.
  • scripts/rea.mjs:8-10 assigns registration helpers to Incur; src/cli.ts:95-103 enables that helper with REA's registration command.

Failure-source evidence at the same revision:

  • node_modules/incur/src/SyncMcp.ts:21-58 selects the Amp-only direct writer and returns its agent list.
  • node_modules/incur/src/SyncMcp.ts:61-84 returns false for JSON read/parse failure and serializes the selected server collection without checking that it is an object map.
  • node_modules/incur/src/Cli.ts:1293-1334 prints success after a returned result; its nonzero error path requires a thrown error.
  • The corresponding executed JavaScript is node_modules/incur/dist/SyncMcp.js:9-66 and node_modules/incur/dist/Cli.js:747-792.

Typed outcome or recovery expected

For these inputs, return a registration failure that identifies the settings file and parse/shape problem, with a nonzero exit status and no registration-success claim. A successful result should correspond to a persisted amp.mcpServers.rea entry. After repairing the configuration and rerunning, the valid-object control should still register normally.

Analysis or suspected cause

Source-derived: malformed JSON makes the writer return false, which only suppresses Amp's name in the result; it does not reach the handler's error path. For an array-valued server collection, assigning a named rea property does not make that property part of the serialized JSON array, yet the writer returns true. Both paths therefore reach success output without a saved registration.

The producing code belongs to the pinned Incur dependency. The failure is nevertheless reachable through REA's documented, shipped registration command, so it is reportable as a REA integration defect. Whether remediation uses a dependency update or a REA boundary change is an implementation decision.

Additional context

Open-and-closed issue searches and all-state PR searches covered mcp add, Amp settings, amp.mcpServers, malformed registration, JSON and Incur. No same-contract duplicate was found. #7375 and its open PR #7453 concern rejecting unexpected positional arguments before writing; this reproduction uses only declared options. #5811 and PR #6347 concern a Windows package-runner spawn failure, which this Amp-only path does not invoke. The first affected release is unknown.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Both unusable-settings fixtures deterministically return success without saving an Amp registration, and the array fixture also reports Amp in the structured result. The observed consequence is bounded registration/status failure rather than severe data loss.
  • Workaround status: available
  • Workaround basis: Valid-object controls and four repair/rerun controls saved the requested entry. A caller can repair the malformed JSON or server-map shape while retaining unrelated settings, then rerun registration.
Originally created by @coygeek on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7536 ### 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 MCP or agent integration ### Observed behavior `node scripts/rea.mjs mcp add --agent amp --command 'node x.mjs' --json` exits 0 and announces `✓ Registered rea as MCP server` even when the existing Amp settings prevent it from saving a registration. For a truncated JSON document, the settings remain byte-identical and the returned `agents` list is empty. For valid JSON containing `"amp.mcpServers": []`, the command additionally claims `Agents: Amp` and returns `"agents": ["Amp"]`, but saves the empty array without a `rea` entry. Both cases have empty stderr and no explanation of the configuration problem. ### Reproduction 1. Use the source revision below, its already installed locked dependencies and compiled runtime, and Node.js v24.22.1 on PATH. Verification used the prepared build; it did not reinstall dependencies or rebuild the checkout. 2. From the checkout root, run this inline fixture/replay. Each command receives an isolated HOME and XDG configuration, cache, data and state directories. The stored `node x.mjs` command is not executed by registration. ```sh python3 -I - <<'PY' import os, pathlib, subprocess, tempfile fixtures = { "malformed": '{ "amp.mcpServers": { "rea": {} ', "array": '{"amp.mcpServers": []}\n', } with tempfile.TemporaryDirectory() as work: for case, fixture in fixtures.items(): root = pathlib.Path(work) / case env = {"PATH": os.environ["PATH"]} for key, part in { "HOME": "home", "XDG_CONFIG_HOME": "home/.config", "XDG_CACHE_HOME": "cache", "XDG_DATA_HOME": "data", "XDG_STATE_HOME": "state", "TMPDIR": "tmp", }.items(): directory = root / part directory.mkdir(parents=True, exist_ok=True) env[key] = str(directory) settings = root / "home/.config/amp/settings.json" settings.parent.mkdir(parents=True, exist_ok=True) settings.write_text(fixture) result = subprocess.run( ["node", "scripts/rea.mjs", "mcp", "add", "--agent", "amp", "--command", "node x.mjs", "--json"], env=env, text=True, capture_output=True, timeout=30, ) print(f"{case}: exit={result.returncode}") print(result.stdout) print(f"stderr={result.stderr!r}") print(f"settings={settings.read_text()!r}") print(f"unchanged={settings.read_text() == fixture}") PY ``` 3. Inspect the printed exit status, success message, agent list and settings bytes. Neither case contains a usable REA registration. Each reproduced in three fresh environments: two initial runs and one replay of this script. ### Expected behavior A registration request should either save the requested server entry or exit nonzero with a diagnostic explaining why registration failed. It should not announce success when no registration was saved, and should not list Amp as registered when its saved settings have no `rea` entry. Existing malformed settings should remain intact when the operation refuses them. The command's public help describes it as registering an MCP server. The product explicitly documents this builtin separately from setup; the specific evidence is listed below. This report does not require setup's transactional implementation or a particular new error code. ### Impact and scope P2: the command's success signals conceal an absent registration for the selected client. Callers relying on exit status or the success message receive no registration-failure indication; the array case also misstates the structured agent result. The settings-file contract failure was observed directly. No live Amp client session or subsequent tool lookup was performed. Valid-object controls saved the expected REA entry twice. Correcting each disposable failing fixture to a valid object and rerunning also saved the entry, demonstrating a repair/rerun workaround. Real settings should be repaired while preserving their unrelated content. Only Amp on the platform below was exercised; other clients, platforms and the frequency of affected real configurations are unknown. ### REA version Exact `node scripts/rea.mjs --version` stdout: ```text 6.8.0 ``` Source commit: `65f1c447344a423fa2785847dbcea1e9a9e2454a`. ### Runtime and platform Node.js v24.22.1; macOS 27.0.1 (build 26A434); arm64. The checkout pins Incur 0.6.1. No analysis provider is involved. ### Target and artifact context Two synthetic Amp settings documents: truncated JSON and an empty array in the server-map field. All writes used disposable directories. No analysis target, credentials or real client configuration was used. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence The inline replay above produced the following reduced output; terminal clearing escapes are omitted. ```text malformed: exit=0 ✓ Registered rea as MCP server Agents can now use rea tools. {"name":"rea","command":"node x.mjs","agents":[]} stderr='' settings='{ "amp.mcpServers": { "rea": {} ' unchanged=True array: exit=0 ✓ Registered rea as MCP server Agents: Amp Agents can now use rea tools. {"name":"rea","command":"node x.mjs","agents":["Amp"]} stderr='' settings='{\n "amp.mcpServers": []\n}\n' unchanged=False ``` Expected-source evidence at the stated revision: - Observed `node scripts/rea.mjs mcp add --help`: `rea mcp add — Register as MCP server`, with `--agent` and `--command` options. - `docs/installation.md:1100-1109` identifies the separate REA builtin and explains that setup does not replace arbitrary command registrations or unsupported-client registrations. - `scripts/rea.mjs:8-10` assigns registration helpers to Incur; `src/cli.ts:95-103` enables that helper with REA's registration command. Failure-source evidence at the same revision: - `node_modules/incur/src/SyncMcp.ts:21-58` selects the Amp-only direct writer and returns its agent list. - `node_modules/incur/src/SyncMcp.ts:61-84` returns false for JSON read/parse failure and serializes the selected server collection without checking that it is an object map. - `node_modules/incur/src/Cli.ts:1293-1334` prints success after a returned result; its nonzero error path requires a thrown error. - The corresponding executed JavaScript is `node_modules/incur/dist/SyncMcp.js:9-66` and `node_modules/incur/dist/Cli.js:747-792`. ### Typed outcome or recovery expected For these inputs, return a registration failure that identifies the settings file and parse/shape problem, with a nonzero exit status and no registration-success claim. A successful result should correspond to a persisted `amp.mcpServers.rea` entry. After repairing the configuration and rerunning, the valid-object control should still register normally. ### Analysis or suspected cause Source-derived: malformed JSON makes the writer return false, which only suppresses Amp's name in the result; it does not reach the handler's error path. For an array-valued server collection, assigning a named `rea` property does not make that property part of the serialized JSON array, yet the writer returns true. Both paths therefore reach success output without a saved registration. The producing code belongs to the pinned Incur dependency. The failure is nevertheless reachable through REA's documented, shipped registration command, so it is reportable as a REA integration defect. Whether remediation uses a dependency update or a REA boundary change is an implementation decision. ### Additional context Open-and-closed issue searches and all-state PR searches covered `mcp add`, Amp settings, `amp.mcpServers`, malformed registration, JSON and Incur. No same-contract duplicate was found. [#7375](https://github.com/morluto/rea/issues/7375) and its open [PR #7453](https://github.com/morluto/rea/pull/7453) concern rejecting unexpected positional arguments before writing; this reproduction uses only declared options. [#5811](https://github.com/morluto/rea/issues/5811) and [PR #6347](https://github.com/morluto/rea/pull/6347) concern a Windows package-runner spawn failure, which this Amp-only path does not invoke. The first affected release is unknown. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Both unusable-settings fixtures deterministically return success without saving an Amp registration, and the array fixture also reports Amp in the structured result. The observed consequence is bounded registration/status failure rather than severe data loss. - Workaround status: available - Workaround basis: Valid-object controls and four repair/rerun controls saved the requested entry. A caller can repair the malformed JSON or server-map shape while retaining unrelated settings, then rerun registration.
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#4477
No description provided.