Repository navigation
fix(core): --server with an Object.prototype name reports not found (#2537) - #2583
Merged
Merged
Conversation
… not found A server name that matches an inherited Object.prototype member (`constructor`, `toString`, ...) resolved to the inherited function on a bare `map[name]` read, so the CLI failed with an unrelated "Cannot use 'in' operator" error instead of "Server 'constructor' not found". Both by-name lookups on the --server path now go through the existing `getOwnEntry` helper (an `Object.hasOwn` read): - `selectServerEntry` in core/mcp/node/servers.ts, which is the lookup the CLI's `--server` actually reaches (and `servers list <name>`); - `loadServerFromConfig` in core/mcp/node/config.ts, the lookup named in the issue (web `--config` + `--server` single mode). Closes #2537 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The narrow fixes reuse the existing helper, preserve valid entries, and include targeted regression coverage with no blocking issues identified.
Review effort: Balanced
Findings: None
What changed in this PR
Fixes #2537 by making shared server-name lookups ignore inherited properties while preserving servers genuinely named constructor.
Changes:
- Uses
getOwnEntryin both by-name lookup paths. - Adds regression tests for absent prototype names and valid
constructorentries.
| File | Description |
|---|---|
| core/mcp/node/servers.ts | Restricts entry selection to own properties. |
| core/mcp/node/config.ts | Restricts config lookup to own properties. |
| clients/web/src/test/core/mcp/node/servers.test.ts | Tests inherited-name rejection and valid entries. |
| clients/web/src/test/core/mcp/node/config.test.ts | Tests equivalent behavior in single-server config resolution. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Member
Author
|
Copilot review closed. Round 1 (review 5411262662) was clean: no inline comments, "Findings: None" in the headline, and no suppressed comments. Per pr-flow 7c, one clean round ends the loop, so I'm not requesting another. |
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2537
Problem
--server constructor(ortoString,hasOwnProperty, ...) against a source that has no such server resolved to the inheritedObject.prototypemember on a baremap[name]read. The CLI then failed withCannot use 'in' operator to search for 'type' in undefinedinstead ofServer 'constructor' not found.Fix
Both by-name server lookups on the
--serverpath now use the existinggetOwnEntryhelper (core/storage/own-entry.ts, anObject.hasOwnread that the repo already uses for the OAuth maps):selectServerEntry(core/mcp/node/servers.ts). The issue's CLI repro actually reaches this one:runCli→loadServerEntries→selectServerEntry(entries, options.server). It is also behindservers list <name>.loadServerFromConfig(core/mcp/node/config.ts). The issue names this one. It is reached byresolveServerConfigs(..., "single")(web--config+--server).A server that really is named
constructorstill resolves normally.Audit of other dynamic reads on this path
I checked the remaining user-keyed reads that
--serverpasses through. I left them alone because none of them is a defect of this class:rehydrateMcpConfigFromKeychain:secrets[id] ?? {}.secretscomes fromsecretStoreGetMany, which writes an own entry (setOwnEntry) for every requested id. Even when a store'sgetManyomits an id, the inherited value is only read for theoauth-client-secret/env:field names, which noFunctionproperty shadows, so it behaves exactly like{}.normalizedServers[name] = …,result[entry.name] = …) only matter for__proto__. The repo already treats__proto__as a reserved id: the routes reject it, and/api/serversdrops it with a warning. Changing that is a different issue, so I kept it out of this PR.--server __proto__now reports "not found", which the new tests pin.Tests
clients/web/src/test/core/mcp/node/config.test.ts:resolveServerConfigssingle mode reports an absentconstructor/toString/hasOwnProperty/__proto__as not found, and resolves a server that really is namedconstructor.clients/web/src/test/core/mcp/node/servers.test.ts: the same cases forselectServerEntry.Gate
npm run formatandnpm run local:gate. In this sandbox, several failures had nothing to do with this diff, so I ran some stages separately:local:validate,verify:skills:cli: green.coverage:web: one failure,secret-store-selection.test.ts > isOnMountPoint > is false when the path itself can't be resolved. The sandbox worktree sits on a mounted volume, so it fails on any branch; a sibling worktree (CLI stored-auth flags (--use-stored-auth, --list-stored-auth, --wait-for-auth) miss tokens stored under byIssuer #2517) sees the same thing. All other 452 files passed. The integration tests that call loopback servers had to run with the sandbox'sHTTP(S)_PROXYunset, because the egress proxy otherwise intercepts them with a 502.coverage:cli,coverage:tui,coverage:launcher,verify:build-gate,verify:bundle-externals,smoke:launcher,smoke:cli,smoke:tui,smoke:web:firefox,local:storybook: green. I ran these individually because the machine-wide gate lease queue was jammed.smoke:web,smoke:web:chromium,smoke:web:tabs: not run locally. The machine-wide gate lease gave up twice after ~46 minutes queued, and running these fixed-port smokes without the lease would collide with other worktrees' gates. CI runs them. This diff only touches the by-name lookups behind CLI--serverand web--config --serversingle mode.🤖 Generated with Claude Code