JavaScript Remove Unused Imports / Organize Imports no-op

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

On a JavaScript (Next.js) project, JavaScript: Remove Unused Imports does not appear in the Command Palette (or does nothing). Organize Imports (Shift+Alt+O) also no longer removes unused imports.
This used to work. Still broken after:

  • TypeScript: Restart TS Server
  • Developer: Reload Window
  • Fixed jsconfig.json (added baseUrl + jsx)
  • Ensured js/ts.experimental.useTsgo is false

Steps to Reproduce

  1. Open a .js file with an unused import (e.g. import never used in the file).
  2. Ctrl+Shift+P → search “Remove Unused Imports”.
  3. Observe: command missing from palette, or runs with no change.
  4. Also try Shift+Alt+O (Organize Imports) — unused imports remain.

Expected Behavior

Unused imports are removed.

Operating System

Windows 10/11

Version Information

  • Cursor: 3.15.6
  • VSCode: 1.128.0
  • Commit: a1f686545fd0ce8917bbd2449f733551a9bce420
  • Quality: stable

Additional Information

  • JavaScript-only project (no TypeScript), jsconfig path aliases.
  • Built-in command javascript.removeUnusedImports is gated by typescript.isManagedFile and !useTsgo.
  • ESLint no-unused-vars still correctly warns about unused imports, so the unused import is real.
  • Binding a custom key to javascript.removeUnusedImports also does nothing.

Does this stop you from using Cursor

No - Cursor works, but with this issue

I am also having a similar issue but with TypeScript files. Organize Imports does nothing via the Command Pallet.

Interesting Organize Imports does work when it is set in codeActionsOnSave.

OS: MacOs
Cursor: 3.15.6

Hey, thanks for the detailed report. Your analysis is spot on, and it also points to the cause.

The Remove Unused Imports command and removing unused imports via Organize Imports only show up when the TS server has a semantic project for the file semantic capability, TS API 4.9 or newer. If the file falls back to syntax-only or partial-semantic mode, the command palette entry is hidden, your custom keybind becomes a no-op, and Organize Imports will sort but won’t remove unused imports. ESLint works independently from the TS server, so it will still flag unused imports. That’s expected and matches what you’re seeing.

What to check, in order:

  • Open a .js file and run TypeScript: Go to Project Configuration. It should resolve to your jsconfig.json. In Next.js projects, if your jsconfig.json doesn’t include "exclude": ["node_modules", ".next"], the project can exceed the tsserver size limit and silently fall back to syntax-only mode. That’s the most common trigger.
  • Check both useTsgo flags in User and Workspace settings, not just js/ts.experimental.useTsgo, but also the legacy typescript.experimental.useTsgo. If you have the TypeScript Native Preview extension typescriptteam.native-preview, disable or uninstall it.
  • Run TypeScript: Select TypeScript Version and check if the workspace is pinned to an old version via typescript.tsdk. Remove Unused Imports requires TypeScript 4.9 or newer.

@Graham_Clifford, based on your description it sounds like the same family of issues. If it works via codeActionsOnSave but not from the palette, the file is probably hitting the same semantic vs syntax-only situation. Run the same checks for your TS project.

Let me know what TypeScript: Go to Project Configuration shows. If it doesn’t resolve to your config, that’s the root cause.

I did create a really simple nodeJS app, and it was able to resolve the tsconfig. But it still will not organize the imports.

TS Version 6.0.3, not using Tsgo

Thanks. I followed the checks you listed.

  1. jsconfig.json exclude
    I added "exclude": ["node_modules", ".next"] as suggested. Behavior did not change.

  2. useTsgo
    Both js/ts.experimental.useTsgo and typescript.experimental.useTsgo are false / unset. No TypeScript Native Preview extension installed.

  3. TypeScript version
    Tried both:

    • VS Code / Cursor bundled TypeScript 6.0.3
    • Workspace TypeScript 5.4.5
      Same issue on both. Remove Unused Imports still missing / no-op, and Organize Imports still does not remove unused imports.
  4. TypeScript output
    Also seeing:

    TSServer exited. Code: null. Signal: SIGTERM
    

    with both TypeScript versions above.


Hey, thanks for running through all the checks. The line TSServer exited. Code: null. Signal: SIGTERM is the main clue. It looks like the issue isn’t your config, it’s that the TS Server itself is crashing. That’s why the file never gets semantic capabilities and all three symptoms line up. The command is hidden, the keybind is a no-op, Organize Imports sorts but doesn’t remove unused, while ESLint still flags things on its own.

To figure out why the server is getting SIGTERM, we’ll need the full TS Server log:

  • Open settings with Ctrl/Cmd+Shift+,, find typescript.tsserver.log, and set it to verbose.
  • Restart with Ctrl/Cmd+Shift+P then TypeScript: Restart TS Server, reproduce the issue in a .js or .ts file.
  • Ctrl/Cmd+Shift+P then TypeScript: Open TS Server Log and paste the contents here, especially the last lines before exited. If you see a notification about tsserver running out of memory, please mention that too.

Also, please clarify:

  • @Khai_Lam, roughly how big is the project, how many files, and are there any large generated folders in scope. Also what does TypeScript: Go to Project Configuration show right now.
  • @Graham_Clifford, does TS Server also crash with SIGTERM in your simple Node.js app, or is the server alive there but Organize Imports still does nothing. This will help confirm if it’s the same scenario.

Once you share the logs, I’ll take a closer look. I’ll post here if there’s an update.

Hi @deanrie ,

Here’s some additional information that may help investigate the issue:

After updating to Cursor v3.15.6, Organize Imports stopped working. I also noticed that the TypeScript server log contains no entries related to organizeImports.

I then downgraded to v3.14.27, but the feature was still broken.

Finally, I downgraded to v3.14.7, where everything started working again. Organize Imports works as expected, and the corresponding organizeImports requests appear in the tsserver log.

@deanrie I do not see “TSServer exited. Code: null. Signal: SIGTERM”

I have also tried running cursor with all extensions disabled as well.

Not sure if this helps, but the latest VSCode does not have this issue (Version: 1.132.0 (Universal)).

Thanks for digging into this, especially the version bisect and the comparison with VS Code. That really helps.

I think we’ve got the full picture now. The fact that Organize Imports and Remove Unused Imports stopped removing unused imports around 3.14.x, even though the TS server is running and reporting diagnostics correctly, is a known issue we’re tracking. It also affects other manually triggered code actions like Source Actions, and it happens regardless of setup, SSH, or devcontainers. The fact that it works in VS Code but not in Cursor, even with extensions disabled, matches this exactly. It’s not something wrong with your configuration.

We’ve found the root cause and the fix is already ready. I can’t share the exact version or date yet, but I’ll reply here as soon as the update ships.

@Khai_Lam, one extra note for your case. The line TSServer exited. Code: null. Signal: SIGTERM is a separate signal. It means the TS Server is actually crashing, and that might not be fixed by the same change that fixes the import no-op. To confirm, we still need a verbose log:

  • Open Settings Ctrl+Shift+, or Cmd+Shift+,, search for typescript.tsserver.log, set it to verbose.
  • Run TypeScript: Restart TS Server, then reproduce the issue in a .js or .ts file.
  • Run TypeScript: Open TS Server Log and paste the contents here, especially the last lines right before exited. If you see any notification about running out of memory, please mention that too.

@Graham_Clifford, you don’t have SIGTERM and VS Code 1.132.0 looks fine. That matches the scenario above. No extra steps needed from you for now, I’ll post an update in this thread when the fix is out.