Skip to content

Resolve relative content mapper packages, always resolve from the config that declares the mapper - #65105

Merged
Andrew Branch (andrewbranch) merged 8 commits into
mainfrom
copilot/fix-relative-package-path-loading
Nov 3, 2026
Merged

Andrew Branch (andrewbranch) merged 8 commits into
mainfrom
copilot/fix-relative-package-path-loading

Conversation

Copilot AI commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Content mapper entries such as "package": "../mapper" could load an ancestor’s package.json, producing misleading diagnostics or silently selecting an unrelated mapper.

  • Resolution: Reject relative and absolute paths before searching node_modules, reporting TS18075. Named and scoped packages retain existing behavior.
  • Regression coverage: Cover existing and nonexistent relative paths, absolute paths, and Windows separators with an unrelated ancestor mapper present.

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix content mappers loading package.json from nearest node_modules Reject filesystem paths in content mapper package resolution Nov 2, 2026
@andrewbranch

Copy link
Copy Markdown
Member

Copilot you're rejecting resolution without any specific config diagnostic? Just "could not be resolved"? Do you think that's a good UX? Is there any principled reason not to allow a relative/absolute path to a package directory in the first place?

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>

Copilot AI commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Copilot you're rejecting resolution without any specific config diagnostic? Just "could not be resolved"? Do you think that's a good UX? Is there any principled reason not to allow a relative/absolut...

No—there isn’t a principled reason to prohibit directory paths, and the generic diagnostic obscured that restriction. Changed in 81140f2 to resolve relative paths from the containing config’s directory and accept absolute directory paths. Both retain manifest validation and workspace authorization; missing paths report TS18075 without falling back to an ancestor package. Added coverage for these cases, including Windows paths and authorization denial. npx hereby validate passed.

@andrewbranch
Andrew Branch (andrewbranch) marked this pull request as ready for review November 3, 2026 16:21
Copilot AI balanced review requested due to automatic review settings November 3, 2026 16:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Inherited relative mapper paths resolve against the consuming config rather than the declaring config, potentially rejecting a valid mapper or silently loading the wrong one.

1 open issue
What changed in this PR

Addresses #65097’s unintended ancestor-package lookup in content mapper resolution. The implementation supports direct filesystem paths rather than rejecting them as the title and description state.

Changes:

  • Resolve relative and absolute package directories before searching node_modules.
  • Add tests for existing and missing paths, Windows separators, and workspace restrictions.
  • Update the resolver comment to describe directory-path support.
File Description
tsc/​internal/​tsoptions/​contentmappers.go Updates the comment to describe direct path resolution.
tsc/​internal/​tsoptions/​contentmappers_test.go Adds filesystem-path resolution and failure cases.
tsc/​internal/​module/​resolver.go Resolves filesystem paths directly before package-name lookup.

Review effort: Balanced

Comment thread tsc/internal/module/resolver.go Resolved
Copilot AI and others added 2 commits November 3, 2026 16:43
Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Directory mappers inside an open workspace are incorrectly rejected when external code is enabled, requiring a policy fix and regression coverage.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Allow in-workspace content mapper directories

tsc/​internal/​module/​resolver.go:544

With /home/project open and external code enabled, a mapper declared as "package": "./mapper" is still rejected in the editor as “outside the open workspace.” IsContentMapperPackageAllowed in tsc/internal/project/configfileregistrybuilder.go:798–808 rejects any directory without a node_modules component, including the in-workspace directory returned here. Update that policy to allow directory mappers inside an open workspace while retaining rejection outside it, and add a project or language-server regression test.

1 resolved since last review

Review effort: Balanced

@andrewbranch

Copy link
Copy Markdown
Member

Copilot fix the "previously missed" comment from the review

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Relative symlinked mapper directories are not canonicalized, causing change notifications for the real package.json to miss the mapper manifest and leave it stale.

1 open issue

Review effort: Balanced

Comment thread tsc/internal/module/resolver.go Resolved

Copilot AI commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

Copilot fix the "previously missed" comment from the review

Fixed in 121727f46: directory mappers are now allowed when their resolved path is inside an open workspace; outside-workspace directories remain denied. Added regression coverage, and npx hereby validate passes.

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues block approval of the content mapper path-resolution changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@andrewbranch Andrew Branch (andrewbranch) changed the title Reject filesystem paths in content mapper package resolution Resolve relative content mapper packages, always resolve from the config that declares the mapper Nov 3, 2026
@andrewbranch
Andrew Branch (andrewbranch) added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit ce8b744 Nov 3, 2026
35 checks passed
@andrewbranch
Andrew Branch (andrewbranch) deleted the copilot/fix-relative-package-path-loading branch November 3, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Content mappers: a relative package path loads the package.json of the nearest folder with node_modules

4 participants