[GH-ISSUE #5828] [Bug] IDA registration validation hides the failed constraint in doctor diagnostics #3527

Closed
opened 2026-10-31 00:41:31 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

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

Area

Provider or capability discovery

Observed behavior

Running node scripts/rea.mjs doctor --provider ida --json with three different schema-invalid IDA registrations produced the same generic registration detail. A native/headless conflict, a non-loopback URL, and a relative workspace root all returned:

REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.

The native/headless file already contains a syntactically valid local URL, and the relative-workspace file already contains a command. The result identifies neither the lifecycle conflict nor the absolute-path requirement. The registration is correctly rejected; its specific failure reason is lost.

Reproduction

From the built source checkout, run the following command once for each JSON fixture below, setting REA_IDA_MCP_CONFIG to that fixture's absolute filename and REA_ANALYSIS_PROVIDER=ida:

node scripts/rea.mjs doctor --provider ida --json

The executed driver supplied an explicit environment with isolated HOME, XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_STATE_HOME, and TMPDIR, plus PATH and those two REA settings. Each subprocess had a 30-second timeout. No real IDA installation or running MCP endpoint was used.

{"mode":"headless","protocol":"native","url":"http://127.0.0.1:13337/mcp"}
{"url":"http://192.0.2.10:13337/mcp"}
{"command":"not-executed-fake-ida","workspaceRoot":"relative"}

Each invocation returned exit 1, healthy: false, and the same registration detail. As a control, the same command with {"command":"not-executed-fake-ida","args":[]} returned exit 0 and healthy: true; doctor reported a valid registration without launching IDA. Each of the four cases was executed once.

Expected behavior

Retain the actionable reason the configuration parser already derives: native protocol requires attached mode, the endpoint must be local and credential-free, or workspaceRoot must be absolute. A generic registration-format message can remain a fallback.

This follows the requirement to preserve meaningful failure reasons and the configuration contract defining each issue as a setting and its failed constraint. The IDA guide explicitly documents rejection of native headless registrations; that rejection should remain in force.

Impact and scope

P3: the demonstrated defect is diagnostic wording. All three invalid registrations remain unavailable, and the valid control passes. No wrong analysis result, cleanup change, target mutation, or security boundary crossing was demonstrated. The missing reason makes configuration repair harder; consulting the guide and correcting the registration is a practical recovery route.

Source inspection shows a shared generic-message branch for registration-schema failures. Unreadable files, malformed JSON, oversize files, and cleanup failures take separate paths, so this report does not claim that every invalid registration has the same message. MCP, setup, analysis commands, other hosts, and real IDA runtime behavior were not exercised.

REA version

rea-agents 6.7.0; source baseline a5f982de8d

Runtime and platform

Node.js v26.12.0; Darwin arm64; no IDA engine or MCP server used.

Target and artifact context

Local IDA registration JSON fixtures; no analysis target or database.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

Trimmed output from node scripts/rea.mjs doctor --provider ida --json; this registration check was identical for all three invalid fixtures:

{
  "name": "registration",
  "ok": false,
  "code": "invalid_configuration",
  "detail": "REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.",
  "remediation": "Set REA_IDA_MCP_CONFIG to your upstream IDA MCP registration JSON; see docs/ida-provider.md.",
  "classification": "config_drift"
}

The containing IDA inspection had configured: true and available: false. The valid control's check was:

{
  "name": "registration",
  "ok": true,
  "code": null,
  "detail": "IDA MCP registration is valid. Upstream availability, compatibility, and target binding are checked when analysis starts; no IDA process was launched.",
  "remediation": null,
  "classification": "config_drift"
}

Doctor's invalid_configuration check code is distinct from the analysis-error envelope's configuration_invalid code.

Typed outcome or recovery expected

Keep doctor's failed registration check and exit status, but explain the actual field or combination that failed. Retain safe constraint facts in the configuration owner's structured settings so downstream callers can use them without parsing raw exception text.

Analysis or suspected cause

Source-derived: the registration schema supplies the specific constraints, but its safeParse failure branch substitutes the generic message and keeps the Zod error only as cause. The configuration-error helper copies that generic string into the setting constraint, and doctor exposes the error message. Extracting safe validation reasons at their owning boundary would address the observed diagnostic loss.

Additional context

No response

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5828 ### 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 Provider or capability discovery ### Observed behavior Running `node scripts/rea.mjs doctor --provider ida --json` with three different schema-invalid IDA registrations produced the same generic registration detail. A native/headless conflict, a non-loopback URL, and a relative workspace root all returned: ```text REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md. ``` The native/headless file already contains a syntactically valid local URL, and the relative-workspace file already contains a command. The result identifies neither the lifecycle conflict nor the absolute-path requirement. The registration is correctly rejected; its specific failure reason is lost. ### Reproduction From the built source checkout, run the following command once for each JSON fixture below, setting `REA_IDA_MCP_CONFIG` to that fixture's absolute filename and `REA_ANALYSIS_PROVIDER=ida`: ```sh node scripts/rea.mjs doctor --provider ida --json ``` The executed driver supplied an explicit environment with isolated `HOME`, `XDG_CONFIG_HOME`, `XDG_CACHE_HOME`, `XDG_STATE_HOME`, and `TMPDIR`, plus `PATH` and those two REA settings. Each subprocess had a 30-second timeout. No real IDA installation or running MCP endpoint was used. ```json {"mode":"headless","protocol":"native","url":"http://127.0.0.1:13337/mcp"} ``` ```json {"url":"http://192.0.2.10:13337/mcp"} ``` ```json {"command":"not-executed-fake-ida","workspaceRoot":"relative"} ``` Each invocation returned exit 1, `healthy: false`, and the same registration detail. As a control, the same command with `{"command":"not-executed-fake-ida","args":[]}` returned exit 0 and `healthy: true`; doctor reported a valid registration without launching IDA. Each of the four cases was executed once. ### Expected behavior Retain the actionable reason the configuration parser already derives: native protocol requires attached mode, the endpoint must be local and credential-free, or `workspaceRoot` must be absolute. A generic registration-format message can remain a fallback. This follows [the requirement to preserve meaningful failure reasons](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/AGENTS.md#L31-L31) and [the configuration contract defining each issue as a setting and its failed constraint](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/src/domain/configurationErrors.ts#L6-L15). The [IDA guide explicitly documents rejection of native headless registrations](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/docs/ida-provider.md#L69-L71); that rejection should remain in force. ### Impact and scope P3: the demonstrated defect is diagnostic wording. All three invalid registrations remain unavailable, and the valid control passes. No wrong analysis result, cleanup change, target mutation, or security boundary crossing was demonstrated. The missing reason makes configuration repair harder; consulting the guide and correcting the registration is a practical recovery route. Source inspection shows a shared generic-message branch for registration-schema failures. Unreadable files, malformed JSON, oversize files, and cleanup failures take separate paths, so this report does not claim that every invalid registration has the same message. MCP, setup, analysis commands, other hosts, and real IDA runtime behavior were not exercised. ### REA version rea-agents 6.7.0; source baseline a5f982de8dbe4b092cc20ab89d492b7e7028b758 ### Runtime and platform Node.js v26.12.0; Darwin arm64; no IDA engine or MCP server used. ### Target and artifact context Local IDA registration JSON fixtures; no analysis target or database. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence Trimmed output from `node scripts/rea.mjs doctor --provider ida --json`; this registration check was identical for all three invalid fixtures: ```json { "name": "registration", "ok": false, "code": "invalid_configuration", "detail": "REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.", "remediation": "Set REA_IDA_MCP_CONFIG to your upstream IDA MCP registration JSON; see docs/ida-provider.md.", "classification": "config_drift" } ``` The containing IDA inspection had `configured: true` and `available: false`. The valid control's check was: ```json { "name": "registration", "ok": true, "code": null, "detail": "IDA MCP registration is valid. Upstream availability, compatibility, and target binding are checked when analysis starts; no IDA process was launched.", "remediation": null, "classification": "config_drift" } ``` Doctor's `invalid_configuration` check code is distinct from the analysis-error envelope's `configuration_invalid` code. ### Typed outcome or recovery expected Keep doctor's failed registration check and exit status, but explain the actual field or combination that failed. Retain safe constraint facts in the configuration owner's structured settings so downstream callers can use them without parsing raw exception text. ### Analysis or suspected cause Source-derived: the [registration schema supplies the specific constraints](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/src/ida/IdaConfiguration.ts#L18-L58), but its [safeParse failure branch substitutes the generic message and keeps the Zod error only as cause](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/src/ida/IdaConfiguration.ts#L116-L130). The [configuration-error helper copies that generic string into the setting constraint](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/src/ida/IdaConfiguration.ts#L214-L222), and [doctor exposes the error message](https://github.com/morluto/rea/blob/a5f982de8dbe4b092cc20ab89d492b7e7028b758/src/ida/IdaDoctor.ts#L45-L60). Extracting safe validation reasons at their owning boundary would address the observed diagnostic loss. ### Additional context _No response_
Author
Owner

@XinwangTao commented on GitHub (Oct 21, 2026):

Confirmed — three distinct schema violations (native+headless conflict, non-loopback URL, relative workspaceRoot) all collapse into the same generic registration message in doctor output, even though the parser already derives the specific reason for each. Keeping those actionable reasons (native requires attached, endpoint must be local and credential-free, workspaceRoot must be absolute) as the primary detail, with the generic format message only as fallback, would make doctor actually repairable instead of forcing users back to the docs.

<!-- gh-comment-id:6312194274 --> @XinwangTao commented on GitHub (Oct 21, 2026): Confirmed — three distinct schema violations (native+headless conflict, non-loopback URL, relative workspaceRoot) all collapse into the same generic registration message in doctor output, even though the parser already derives the specific reason for each. Keeping those actionable reasons (native requires attached, endpoint must be local and credential-free, workspaceRoot must be absolute) as the primary detail, with the generic format message only as fallback, would make doctor actually repairable instead of forcing users back to the docs.
Author
Owner

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

Checked the reported fix on main at d87e73f2db.

readIdaConfiguration projects schema-authored field constraints into the primary ConfigurationError message and structured settings; it retains a generic fallback only when no safe issue text exists. IdaDoctor exposes that message as registration detail. The CLI regression includes the original native/headless conflict, exact non-loopback fixture, relative workspaceRoot and valid command control.

Implementation: IdaConfiguration.ts, IdaConfiguration.ts.

The relevant regression checks in idaDoctorRegistration.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380693397 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. readIdaConfiguration projects schema-authored field constraints into the primary ConfigurationError message and structured settings; it retains a generic fallback only when no safe issue text exists. IdaDoctor exposes that message as registration detail. The CLI regression includes the original native/headless conflict, exact non-loopback fixture, relative workspaceRoot and valid command control. Implementation: [IdaConfiguration.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/ida/IdaConfiguration.ts#L139), [IdaConfiguration.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/ida/IdaConfiguration.ts#L158). The relevant regression checks in [idaDoctorRegistration.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/cli/idaDoctorRegistration.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3527
No description provided.