[BUG] JetBrains plugin: diff "before" pane is always empty for a project opened over `\\wsl$\` (WSL, no reverse-direction path mapping works)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When Claude Code edits an existing file and opens a diff for confirmation, the diff view's left ("before") pane is always empty. The right ("after") pane always renders correctly. This makes the IDE diff useless for reviewing changes before accepting — the only way to see what actually changed is to read the terminal output, which only shows the diff once the change has already been accepted.
What Should Happen?
left pane is blank; right pane shows the proposed content correctly.
Error Messages/Logs
Steps to Reproduce
- Open a project that lives inside a WSL distro, in PhpStorm running natively on Windows, via
\\wsl$\<distro>\...(not JetBrains Gateway/remote dev, not/mnt/c/...). - Run
claudefrom a terminal inside that same WSL distro (e.g. the JetBrains-integrated terminal), with/ideconnected to the PhpStorm instance. - Ask Claude to edit an existing file (any small text change).
- Observe the diff tab that opens in PhpStorm.
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude Code CLI v2.1.233
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
Environment
- Plugin: Claude Code JetBrains Plugin (
com.anthropic.code.plugin), v0.1.14-beta — confirmed up to date via the plugin's own update check - IDE: PhpStorm build PS-262.9437.196 (2026.2); same behavior reproduced on PhpStorm 2026.1 with the plugin's plugin-settings applied there too
- Host: Windows, PhpStorm installed natively (not JetBrains Gateway / remote dev)
- Project location: inside WSL2 (Debian Bookworm distro), project opened in PhpStorm via the UNC path
\\wsl$\DebianBookWorm\var\www\<project> - Claude Code CLI: v2.1.233, run from the JetBrains-integrated terminal inside the same WSL distro, connected to the IDE via the plugin (
claude /statusreports "IDE: Connected to PhpStorm extension")
Root cause (from decompiling the plugin jar)
DiffTools.addTools()'s openDiff handler resolves the "before" side by:
- Taking
old_file_path(a plain Linux path, e.g./var/www/project/foo.php) from the MCP tool args. - Calling
com.anthropic.code.plugin.UtilsKt.convertToOSFilePath(path, project), which:
- Passes through paths already matching
^[A-Za-z]:/.*$. - Converts
/mnt/<drive>/...paths to<DRIVE>:/...if "Enable automatic Windows drive mapping" is on. - Otherwise, if "Enable automatic WSL localhost mapping" is on, prefixes the path with an
effectivePathPrefix— either a user-configured override or one auto-extracted fromproject.getBasePath()via the regex^(//wsl[^/]*/[^/]+)/.*$.
- Passing the resulting string to
UtilsKt.openVirtualFileFromPath(path, projectDir), which resolves it viaLocalFileSystem.getInstance()inside arunReadAction. - The "after" side, by contrast, is built directly from the
new_file_contentsstring sent in the tool call — no file resolution needed, which is why it always works regardless of any of the above.
The right-hand side text is exactly what worked as expected — the "before" side is the only one depending on this path-translation + LocalFileSystem resolution chain, which is failing silently.
What we tried (all confirmed NOT the fix)
- Confirmed both "Enable automatic Windows drive mapping (C:\ to /mnt/c/)" and "Enable automatic WSL localhost mapping" were already ON in Settings → Tools → Claude Code [Beta] → MS Windows/WSL Configuration.
- Manually set the "WSL localhost path" override to the literal
\\wsl$\DebianBookWormprefix (matching how the project is actually opened) + restarted PhpStorm — no change. Reverted to blank/auto-detect afterward, also no change. - Enabled DEBUG logging for
#com.anthropic.code.plugin(Help → Diagnostic Tools → Debug Log Settings) and reproduced the bug — zero log lines were emitted by the plugin, even at DEBUG level, during the failing diff. This strongly suggestsopenVirtualFileFromPath(or an earlier step) returnsnull/empty silently rather than throwing, and the diff code renders that as blank content without ever logging anything. - Full PhpStorm restarts and
/idereconnects in the CLI — no effect on this specific bug (they did surface an unrelated CLI-side issue, see note below). - Checked PhpStorm's Registry (Help → Find Action → "Registry...") for anything WSL/IJent related that could be interfering: found
wsl.p9.support,wsl.prefer.p9.support,wsl.use.remote.agent.for.launch.processes(already off, user-set), and genericijent.*tuning flags — no master on/off switch for WSL's newer file-access backend was found.
Possibly relevant environment detail
PhpStorm's own log (idea.log) repeatedly shows:
INFO - #c.i.p.i.i.w.EelWslMrfsBackend - Switching DebianBookWorm to IJent WSL nio.FS: IjentWslNioFileSystem(IjentWslNioFileSystemProvider(DebianBookWorm))
This is JetBrains' newer "Eel/IJent" WSL filesystem backend, active for this project's WSL connection. It's possible the plugin's LocalFileSystem.findFileByPath()-based resolution doesn't interoperate correctly with this backend, though we could not confirm this — no user-facing setting exists to disable IJent for WSL specifically, and a search across the entire PhpStorm install (1264 jars) for the classes involved (EelWslMrfsBackend, WslIjentAvailabilityService) turned up nothing, so we couldn't inspect that code path further from the client side. Note that git4idea submodule-check log lines confirm the IDE still addresses project files via the classic file:////wsl$/<distro>/... URI scheme underneath, so this may not be a full replacement of the classic path space — unclear.
Suggested next steps for maintainers
- Add logging (even at DEBUG) around the actual
LocalFileSystemresolution call inopenVirtualFileFromPath/convertToOSFilePath, specifically logging the final resolved path string and whether the returnedVirtualFilewas null, so this failure mode is diagnosable without decompiling. - Consider a fallback: if
old_file_pathcan't be resolved viaLocalFileSystem, read the file directly via NIO (Files.readString(Paths.get(...))) using the WSL-translated path, rather than relying solely onLocalFileSystem.findFileByPath(). - If this turns out to be an IJent/Eel-WSL-backend interoperability issue specifically, it would be worth testing whether
LocalFileSystem.refreshAndFindFileByPath()(which force-refreshes the VFS) behaves differently than a plainfindFileByPath()call in this environment.
---
Separately, we ran into an unrelated red herring worth noting in case others hit it: if the CLI's permission mode is set to "auto-accept edits" (Shift+Tab cycles through modes), no diff tab opens at all — not blank, just absent — since there's no confirmation step to show. Not a bug, just worth ruling out first.