Skip to content

LSP: newly created file is assigned to the wrong project when the project path contains '[' / '{' (or include differs only by case) #64987

Open

Description

🔎 Search Terms

PossiblyMatchesFileName, WildcardDirectoryGlobs, glob brackets, glob escape, square brackets path, curly braces directory, new file wrong project, newly created file not included in project, include case insensitive

🕗 Version & Regression Information

⏯ Playground Link

N/A: this needs files on disk in a folder with [ in its name, two nested tsconfigs, and a file-created event, which the Playground can't reproduce.

💻 Code

Layout (note the [ws] folder in the path):

/tmp/x/[ws]/monorepo/tsconfig.json
{"compilerOptions":{"target":"ES2015","lib":["ES2015"],"noEmit":true,"types":[]},"include":["apps"]}

/tmp/x/[ws]/monorepo/apps/web/tsconfig.json
{"compilerOptions":{"target":"ESNext","lib":["ESNext"],"noEmit":true,"types":[]},"include":["app"]}

/tmp/x/[ws]/monorepo/apps/web/app/existing.ts

export const a = [1, 2].findLast(x => x > 0);

Steps:

  1. Start tsgo --lsp --stdio with the workspace at /tmp/x/[ws]/monorepo.
  2. Open apps/web/app/existing.ts. No diagnostics (correct).
  3. Create apps/web/app/subdir/new.ts on disk:
export const b = [1, 2].findLast(x => x > 0);
  1. Send workspace/didChangeWatchedFiles (type Created) for new.ts, then textDocument/didOpen it. The other order gives the same result.
  2. Request textDocument/diagnostic for new.ts.

Same result with a {ws} folder, or with a plain path on a case-insensitive filesystem where apps/web/tsconfig.json has "include": ["App"] but the folder on disk is "app".

🙁 Actual behavior

new.ts is served by the parent project (lib: ES2015) instead of apps/web/tsconfig.json, so it gets false errors:

TS2550: Property 'findLast' does not exist on type 'number[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2023' or later.
(plus a follow-on TS7006 for the lambda parameter losing its contextual type)

The errors are still present 5 seconds later and only go away after restarting the language server.

🙂 Expected behavior

new.ts should belong to apps/web/tsconfig.json and have no diagnostics. That's what happens when the same layout is in a folder without [ or {, and with tsgo -p apps/web on the command line (it lists new.ts and reports 0 errors).

Additional information about the issue

Cause (at commit 4163ca1): for a file Created event, configfileregistrybuilder.go (~line 613) only checks ParsedCommandLine.PossiblyMatchesFileName, which matches against globs from WildcardDirectoryGlobs() (tsoptions/parsedcommandline.go ~317–318 and ~511–513). Those globs are built as /**/*.{ts,...} straight from the raw directory path, so:

  • "[ws]" doesn't parse as a glob; the parse error is ignored and the glob is silently dropped.
  • "{ws}" / "{b,c}" are read as alternation groups and "app[1-2]" as a character range, so the real folder name never matches.
  • Matching is exact-case, even on case-insensitive filesystems.

Possible fix: don't build globs from filesystem paths. Either escape the special characters, or check the new file directly against the wildcard directories using caseSensitivity.PathKey (recursive dirs contain it, non-recursive dirs equal its parent, extension is supported). Also, don't silently drop patterns that fail to parse.

tsc --watch did not show the problem in my testing because a directory-change fallback picks the file up.

Tested with a synthetic LSP client, not VS Code.

AI disclosure: this issue was found and drafted with the help of an AI coding agent. I reviewed and reproduced it myself.

Activity

  1. jakebailey commented on Oct 28, 2026

    @jakebailey
    Member

    this issue was found and drafted with the help of an AI coding agent

    Meaning, you hit this bug, and asked an agent to investigate? Or, you asked an agent to find a bug?

  2. 1-DARK commented on Oct 28, 2026

    @1-DARK
    ContributorAuthor

    Hi Jake Bailey (@jakebailey), I asked an agent to audit the repo for bugs, and this is what it found. I didn't hit it in my own day-to-day use.

    I did reproduce it myself end-to-end with the built tsgo --lsp --stdio binary (not just a unit test): with the project under
    a [ws] or {ws} directory, a newly created file gets served by the parent project and shows the false TS2550, while the same layout without brackets, and tsgo -p on the CLI, are fine. I can share the small repro script if useful.

    I understand if this is too much of an edge case to prioritize - feel free to close it if so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions