[GH-ISSUE #2665] fix(setup): report runtime-invalid server overrides instead of aligned registrations #966

Closed
opened 2026-10-15 18:29:57 +00:00 by bsakaguchi · 1 comment
Owner

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

Summary

A Cursor registration with HOPPER_LOADER_ARGS_JSON set to { is reported as current by setup and aligned by doctor, although MCP startup rejects that value before starting its transport. The invalid value survives setup unchanged, leaving the client unable to connect while the registration diagnostics give no remediation. An explicitly configured compiler specification without its required language identifier has the same mismatch.

Steps to reproduce

The observations below come from focused source tests on the baseline listed under Runtime or environment. The public CLI subprocess and released package were not run. The following portable test uses the same registration shape and production functions, with an owned disposable directory instead of any existing client configuration.

  1. In a source checkout with its locked dependencies available, save this test as src/application/registration-environment-repro.test.ts:
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { expect, it } from "vitest";
import { run } from "../main.js";
import {
  clientConfigurationAligned,
  configureClientConfiguration,
  inspectClientConfiguration,
} from "./SetupClientConfiguration.js";
import { readClientRegistrationStatuses } from "./ClientRegistrationStatus.js";

it("compares registration diagnostics with MCP startup", async () => {
  const home = await mkdtemp(join(tmpdir(), "registration-environment-"));
  try {
    const launcher = resolve("scripts/rea.mjs");
    const command = [launcher, "mcp"];
    const env = { HOPPER_LOADER_ARGS_JSON: "{" };
    await mkdir(join(home, ".cursor"));
    const configPath = join(home, ".cursor", "mcp.json");
    const original = JSON.stringify({
      mcpServers: { rea: { command: launcher, args: ["mcp"], env } },
    });
    await writeFile(configPath, original);
    const client = { name: "cursor", format: "json", configPath } as const;
    expect(await inspectClientConfiguration(client, {}, command))
      .toEqual({ status: "already_current" });
    expect(await clientConfigurationAligned(client, {}, command)).toBe(true);
    expect(await configureClientConfiguration(client, {}, command))
      .toEqual({ status: "unchanged" });
    const statuses = await readClientRegistrationStatuses(home, launcher, {
      environment: {}, platform: "darwin",
    });
    expect(statuses.find(({ client }) => client === "cursor")?.state)
      .toBe("aligned");
    let stderr = "";
    const code = await run({
      env,
      serve: async () => { throw new Error("Transport must not start"); },
      writeStderr: (text) => { stderr += text; },
      setExitCode: () => {},
      registerShutdown: () => () => {},
    });
    expect(code).toBe(1);
    expect(stderr).toBe(
      "REA configuration is invalid: HOPPER_LOADER_ARGS_JSON must be valid JSON.\n",
    );
    expect(await readFile(configPath, "utf8")).toBe(original);
  } finally {
    await rm(home, { recursive: true, force: true });
  }
});
  1. Run the source test. These assertions describe the observed defect and pass on the inspected source:
npm run test:local -- src/application/registration-environment-repro.test.ts

The executed verification also substituted { REA_GHIDRA_COMPILER_SPEC_ID: "borlandcpp" } for the environment map. Its registration diagnostics gave the same results, while MCP startup returned 1 with REA_GHIDRA_COMPILER_SPEC_ID: requires REA_GHIDRA_LANGUAGE_ID.

Expected behavior

Setup and doctor must identify an explicit registration override that REA rejects at startup, name the offending setting, and let the caller repair it before setup writes files. The installation guide promises this for invalid runtime settings. The valid portions of the environment map should remain available for correction.

Actual behavior

The focused test observed inspectClientConfiguration return already_current, clientConfigurationAligned return true, configureClientConfiguration return unchanged, and the registration-status reader used by doctor return aligned. The registration bytes remained unchanged and no backup was created. Calling the real MCP run entry point with the same environment returned 1 and wrote:

REA configuration is invalid: HOPPER_LOADER_ARGS_JSON must be valid JSON.

The injected transport was never called. Valid [] loader JSON and a paired REA_GHIDRA_LANGUAGE_ID=x86:LE:32:default with REA_GHIDRA_COMPILER_SPEC_ID=borlandcpp passed the runtime parser and registration checks. An invalid REA_MCP_INPUT_SCHEMA_PROFILE=bogus was correctly reported invalid by the same inspection/status functions. Five focused tests passed in total.

Evidence

  • Expected source: docs/installation.md:55-65 promises setup/doctor diagnostics for invalid runtime settings before writes; tests/boundary/filesystem/clientConfigurationEnvironment.test.ts:111-182 enforces this for existing invalid-profile and response-budget cases; src/config/parseConfig.ts:39-63 defines the additional startup constraints.
  • Failure source: The focused source tests exercised src/application/SetupClientConfiguration.ts:259,303, src/application/ClientRegistrationStatus.ts:142-145, and src/main.ts:53-58 against the same owned Cursor registration and explicit environment. src/application/ClientRegistrationEnvironment.ts:49 calls only parseEnvironment; src/application/ClientConfigurationFiles.ts:88 accepts its result without the additional startup checks.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Related: #1606 covers preservation of valid server overrides; #1183 covers provider-admission handling of relative installation paths.

Restoration check

With the same loader-JSON or unpaired-compiler override, setup inspection and doctor registration diagnostics should report an invalid registration with the named setting. Setup must preserve the existing file instead of reporting that the invalid override is current or retaining it in a proposed update without a diagnostic. Keep the existing invalid-profile behavior. Valid loader arrays, paired language/compiler settings, and unrelated string overrides must remain accepted and preserved.

Runtime or environment

Inspected and tested source commit: a2d8b94dd50dab8d966239dd63ab84718aa8b4b4. Source tests used Node 24.18.0 and npm 11.16.0. Cursor status inspection selected the macOS client-layout branch explicitly. The latest published package supplied for comparison was rea-agents 6.4.0; its installed runtime was not tested.

Current upstream recheck at 3ae826ceba6f25b08bce50bcb51001209bc16b57 repeated all five focused source observations and controls with the same Node and npm versions and confirmed that both registration/startup mismatches remain; the public CLI subprocess, released runtime, other client dialects, and provider connections were not executed.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Particular explicit server overrides prevent MCP startup while setup and doctor report the registration as current or aligned. The observed failure is limited to affected registrations and is reversible.
  • Workaround status: available
  • Workaround basis: Correct or remove the invalid loader-JSON override, or supply the required language identifier with the compiler setting. The valid array and paired-setting controls passed the runtime parser without a code change.
Originally created by @coygeek on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2665 ## Summary A Cursor registration with `HOPPER_LOADER_ARGS_JSON` set to `{` is reported as current by setup and aligned by doctor, although MCP startup rejects that value before starting its transport. The invalid value survives setup unchanged, leaving the client unable to connect while the registration diagnostics give no remediation. An explicitly configured compiler specification without its required language identifier has the same mismatch. ## Steps to reproduce The observations below come from focused source tests on the baseline listed under Runtime or environment. The public CLI subprocess and released package were not run. The following portable test uses the same registration shape and production functions, with an owned disposable directory instead of any existing client configuration. 1. In a source checkout with its locked dependencies available, save this test as `src/application/registration-environment-repro.test.ts`: ```typescript import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { expect, it } from "vitest"; import { run } from "../main.js"; import { clientConfigurationAligned, configureClientConfiguration, inspectClientConfiguration, } from "./SetupClientConfiguration.js"; import { readClientRegistrationStatuses } from "./ClientRegistrationStatus.js"; it("compares registration diagnostics with MCP startup", async () => { const home = await mkdtemp(join(tmpdir(), "registration-environment-")); try { const launcher = resolve("scripts/rea.mjs"); const command = [launcher, "mcp"]; const env = { HOPPER_LOADER_ARGS_JSON: "{" }; await mkdir(join(home, ".cursor")); const configPath = join(home, ".cursor", "mcp.json"); const original = JSON.stringify({ mcpServers: { rea: { command: launcher, args: ["mcp"], env } }, }); await writeFile(configPath, original); const client = { name: "cursor", format: "json", configPath } as const; expect(await inspectClientConfiguration(client, {}, command)) .toEqual({ status: "already_current" }); expect(await clientConfigurationAligned(client, {}, command)).toBe(true); expect(await configureClientConfiguration(client, {}, command)) .toEqual({ status: "unchanged" }); const statuses = await readClientRegistrationStatuses(home, launcher, { environment: {}, platform: "darwin", }); expect(statuses.find(({ client }) => client === "cursor")?.state) .toBe("aligned"); let stderr = ""; const code = await run({ env, serve: async () => { throw new Error("Transport must not start"); }, writeStderr: (text) => { stderr += text; }, setExitCode: () => {}, registerShutdown: () => () => {}, }); expect(code).toBe(1); expect(stderr).toBe( "REA configuration is invalid: HOPPER_LOADER_ARGS_JSON must be valid JSON.\n", ); expect(await readFile(configPath, "utf8")).toBe(original); } finally { await rm(home, { recursive: true, force: true }); } }); ``` 2. Run the source test. These assertions describe the observed defect and pass on the inspected source: ```bash npm run test:local -- src/application/registration-environment-repro.test.ts ``` The executed verification also substituted `{ REA_GHIDRA_COMPILER_SPEC_ID: "borlandcpp" }` for the environment map. Its registration diagnostics gave the same results, while MCP startup returned 1 with `REA_GHIDRA_COMPILER_SPEC_ID: requires REA_GHIDRA_LANGUAGE_ID`. ## Expected behavior Setup and doctor must identify an explicit registration override that REA rejects at startup, name the offending setting, and let the caller repair it before setup writes files. The installation guide promises this for invalid runtime settings. The valid portions of the environment map should remain available for correction. ## Actual behavior The focused test observed `inspectClientConfiguration` return `already_current`, `clientConfigurationAligned` return `true`, `configureClientConfiguration` return `unchanged`, and the registration-status reader used by doctor return `aligned`. The registration bytes remained unchanged and no backup was created. Calling the real MCP `run` entry point with the same environment returned 1 and wrote: ```text REA configuration is invalid: HOPPER_LOADER_ARGS_JSON must be valid JSON. ``` The injected transport was never called. Valid `[]` loader JSON and a paired `REA_GHIDRA_LANGUAGE_ID=x86:LE:32:default` with `REA_GHIDRA_COMPILER_SPEC_ID=borlandcpp` passed the runtime parser and registration checks. An invalid `REA_MCP_INPUT_SCHEMA_PROFILE=bogus` was correctly reported invalid by the same inspection/status functions. Five focused tests passed in total. ## Evidence - Expected source: `docs/installation.md:55-65` promises setup/doctor diagnostics for invalid runtime settings before writes; `tests/boundary/filesystem/clientConfigurationEnvironment.test.ts:111-182` enforces this for existing invalid-profile and response-budget cases; `src/config/parseConfig.ts:39-63` defines the additional startup constraints. - Failure source: The focused source tests exercised `src/application/SetupClientConfiguration.ts:259,303`, `src/application/ClientRegistrationStatus.ts:142-145`, and `src/main.ts:53-58` against the same owned Cursor registration and explicit environment. `src/application/ClientRegistrationEnvironment.ts:49` calls only `parseEnvironment`; `src/application/ClientConfigurationFiles.ts:88` accepts its result without the additional startup checks. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Related: #1606 covers preservation of valid server overrides; #1183 covers provider-admission handling of relative installation paths. ## Restoration check With the same loader-JSON or unpaired-compiler override, setup inspection and doctor registration diagnostics should report an invalid registration with the named setting. Setup must preserve the existing file instead of reporting that the invalid override is current or retaining it in a proposed update without a diagnostic. Keep the existing invalid-profile behavior. Valid loader arrays, paired language/compiler settings, and unrelated string overrides must remain accepted and preserved. ## Runtime or environment Inspected and tested source commit: `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`. Source tests used Node 24.18.0 and npm 11.16.0. Cursor status inspection selected the macOS client-layout branch explicitly. The latest published package supplied for comparison was rea-agents 6.4.0; its installed runtime was not tested. Current upstream recheck at `3ae826ceba6f25b08bce50bcb51001209bc16b57` repeated all five focused source observations and controls with the same Node and npm versions and confirmed that both registration/startup mismatches remain; the public CLI subprocess, released runtime, other client dialects, and provider connections were not executed. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Particular explicit server overrides prevent MCP startup while setup and doctor report the registration as current or aligned. The observed failure is limited to affected registrations and is reversible. - Workaround status: available - Workaround basis: Correct or remove the invalid loader-JSON override, or supply the required language identifier with the compiler setting. The valid array and paired-setting controls passed the runtime parser without a code change.
bsakaguchi 2026-10-15 18:29:57 +00:00
Author
Owner

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

Addressed on main in ec56c1da0.

Setup and doctor validate retained effective registration overrides through the same runtime configuration owner, including layered OpenCode sources.

Validation: Layered registration/environment tests and package setup verification passed; static gate passed.

Verification scope: Configured values remain caller-owned; validation does not execute a package runner.

<!-- gh-comment-id:6158661423 --> @morluto commented on GitHub (Oct 14, 2026): Addressed on main in [ec56c1da0](https://github.com/morluto/rea/commit/ec56c1da0). Setup and doctor validate retained effective registration overrides through the same runtime configuration owner, including layered OpenCode sources. Validation: Layered registration/environment tests and package setup verification passed; static gate passed. Verification scope: Configured values remain caller-owned; validation does not execute a package runner.
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#966
No description provided.