You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I clicked on one of the inline runnable buttons (introduced by #79) for a test or main class and got this error:
At line:1 char:113
+ ... st"; m="merge_differentTypesAddedToKey_onlyLatestIsAdded"; if [ -f po ...
+ ~
Missing '(' after 'if' in if statement.
At line:1 char:115
+ ... "; m="merge_differentTypesAddedToKey_onlyLatestIsAdded"; if [ -f pom. ...
+ ~
Missing type name after '['.
At line:1 char:228
+ ... if [ -f gradlew ]; then ./gradlew test --tests $c.$m; else >&2 echo ' ...
+ ~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingOpenParenthesisInIfStatement
Cause: The tasks definitions use shell scripts which don't run on Windows.
What did you expect to happen?
I expected the test/main class to run.
Environment
Zed: v0.208.0 (Zed Nightly 21e75b82216d91d46f03040d040ab9ef00fa763b)
OS: Windows 10.0.19045
Architecture: x86_64
I had a similar issue because I am using fish as my default shell and fixed it with #93 but I am not sure this is going to translate for Windows (it still expects to find a POSIX-shell at /bin/sh).
I'd generally like to make these runnable scripts a bit more robust than what they are, and the user should probably also get an opportunity to configure them, but I'm not quite sure what the best approach would be to doing so - my first instinct was to have proper scripts in the extension folder and publish them via ENV-vars. Maybe someone has a better idea?
I saw your PR but didn't comment on it because I didn't want to risk it being delayed (merging it as-is as opposed to waiting until a platform-agnostic solution is in place).
Setting up platform-specific scripts and then using them depending on platform could be a way, but I don't know if that is possible to configure at the moment?
There is actually a workaround that I found:
if you create a tasks.json in your project_root/.zed/ directory you can (re-)define the tasks on a per-project basis using any command you like, and zed will prioritize them over the ones provided by the extension.
So specifically:
create a file tasks.json in the .zed-directory with a list of TaskTemplates (the best documentation I found for how they work is in the Zed source codein the docs), here's an example:
[
{
"label": "Custom Run Test $ZED_CUSTOM_java_class_name.$ZED_CUSTOM_java_method_name",
"command": "mvn test -Dtest=$ZED_CUSTOM_java_class_name#$ZED_CUSTOM_java_method_name",
"use_new_terminal": false,
"reveal": "always",
"tags": ["java-test-method"]
}
]
I don't quite understand when zed will refresh these, I had to sometimes run them manually from the Run>Spawn Task-modal (they will show up if your cursor is at a relevant spot, e.g. a test method)
The label property and the command can be whatever you want and the command will default to your default shell running from your project root directory.
The tags is the magic ingredient and they will have to match the tags we set in our runnables.scm.
Currently they are few and self-explanatory:
java-main
java-test-method
java-test-class
and you can use these captures as environment-vars:
ZED_CUSTOM_java_package_name
ZED_CUSTOM_java_class_name
ZED_CUSTOM_java_method_name
(plus a bunch more that Zed provides by default but tend to not be relevant for running scripts).
I think other than that, besides providing best-effort defaults we should just document how to do this and encourage people to bring their own tasks until zed-industries/zed#17462 gets some attention.
There is actually a workaround that I found:
if you create a tasks.json in your project_root/.zed/ directory you can (re-)define the tasks on a per-project basis using any command you like, and zed will prioritize them over the ones provided by the extension.
Weird, that was one of the first things I tested after I first tried to use the runnable, and that time it refused to work. As soon as I added anything with a $ to the task command it wouldn't show up anywhere.
But I just tried overriding with a custom task again and now it seems to work perfectly. 🤔
Your suggested work around doesnt work for multi maven module project. Are there other zed custome variables to detect the root of the sub modules when trying to execute specific test class of a sub modules?
I am using Zed to run JUnit tests in a Maven Java project.
Running the whole test class works correctly. For example, when I run UserServiceTest, Maven successfully finds and runs the test method, and the output shows:
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
However, when I try to run a single test method from Zed, Maven does not execute any test. The output shows:
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
The problem appears to be in Zed’s tasks.json configuration for running a single test method.
The generated Maven command is:
mvn clean test '-Dtest=com.javaweb.UserServiceTest#ZED_CUSTOM_java_method_name'
But it should be:
mvn clean test '-Dtest=com.javaweb.UserServiceTest#testIsValidUsername'
In tasks.json, the method name variable is missing the $ symbol.
The incorrect configuration is:
#ZED_CUSTOM_java_method_name
The correct configuration should be:
#$ZED_CUSTOM_java_method_name
Because of this typo, Maven tries to run a method literally named ZED_CUSTOM_java_method_name, which does not exist. As a result, no test method is executed.
error info:
&: The term '/bin/sh' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
⏵ Task Run GenieAdminApplication finished with exit code: 1
⏵ Command: /bin/sh -i -c 'pkg="com.XX"; cls="XXXApplication"; if [ -n "$pkg" ]; then c="$pkg.$cls"; else c="$cls"; fi; f="D:\code\XXX\XXXApplication.java"; p="$PWD"; d=$(dirname "${f#$p/}"); if [ -f pom.xml ]; then m="."; md="$d"; while [ "$md" != "." ] && [ "$md" != "/" ]; do if [ -f "$md/pom.xml" ]; then m="$md"; break; fi; md=$(dirname "$md"); done; [ -f ./mvnw ] && CMD="./mvnw" || CMD="mvn"; case "$f" in "/src/test/") COMPILE_GOAL="test-compile"; CLASSPATH_SCOPE="test";; ) COMPILE_GOAL="compile"; CLASSPATH_SCOPE="runtime";; esac; if [ "$m" = "." ]; then $CMD clean $COMPILE_GOAL exec:java -Dexec.mainClass="$c" -Dexec.classpathScope=$CLASSPATH_SCOPE; else $CMD clean $COMPILE_GOAL -pl "$m" -am && $CMD exec:java -pl "$m" -Dexec.mainClass="$c" -Dexec.classpathScope=$CLASSPATH_SCOPE; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m="."; md="$d"; while [ "$md" != "." ] && [ "$md" != "/" ]; do if [ -f "$md/build.gradle" ] || [ -f "$md/build.gradle.kts" ]; then m="$md"; break; fi; md=$(dirname "$md"); done; if [ "$m" = "." ]; then mp=""; else mp=":$(echo "$m" | tr '/' ':')"; fi; [ -f ./gradlew ] && CMD="./gradlew" || CMD="gradle"; $CMD ${mp}:run -PmainClass="$c"; else find . -name '.java' -not -path './bin/' -not -path './target/' -not -path './build/*' -print0 | xargs -0 javac -d bin && java -cp bin "$c"; fi;'
By the way, there is another alternative fix for this: you can symlink /bin/sh to to Git Bash or another unix-shell emulator (provided that you have one installed):
# Create the bin directory at the root of C:New-Item-ItemType Directory -Path "C:\bin"-Force
# Create a symbolic link pointing to your Bash emulatorNew-Item-ItemType SymbolicLink -Path "C:\bin\sh.exe"-Target "C:\Program Files\Git\bin\sh.exe"
Disclaimer: I haven't tried this as I don't have a Windows environment
and the command bodies are POSIX scripts ([ -f pom.xml ], $(dirname ...), find ... -print0 | xargs -0). On a stock Windows install there is no /bin/sh to spawn at all, so it fails at process creation rather than at PowerShell parse time — the variant in the original report above.
Noting for anyone landing here before #252 ships (main still has 5 /bin/sh occurrences as of v6.8.24): a user-level tasks.json is a workable stopgap on Windows for the no-build-tool case, using JDK 11+'s single-file source launcher:
One gotcha that cost me a round trip and may be worth documenting: Zed appends its own shell flag (-C on Windows, -i -c on POSIX) after the args you supply. Putting -Command in args yields
Still reproducing on 6.8.26, Windows 11. There is a second bug hiding behind the shell one, and fixing /bin/sh alone won't be enough.
To test, I ran the java-main task script under Git Bash's sh.exe. That gets past the spawn failure, but the module detection still produces an invalid Maven invocation. The script does:
f="$ZED_FILE"; p="$PWD"; d=$(dirname "${f#$p/}")
On Windows, $ZED_FILE is a backslash path (C:\Users\me\myproject\...\App.java) while $PWD in a POSIX shell is /c/Users/me/myproject, so the prefix strip never matches. d stays absolute, the walk-up loop finds the root pom.xml, and m ends up as the absolute project root instead of .:
Maven rejects that, since -pl expects a path relative to the reactor. This is a single-module project with pom.xml at the worktree root, where the expected result is m=".".
The module detection came in with #244, so this part postdates the original report here. It may also be what @prashanth057 hit above with multi-module projects.
Practical consequence: the C:\bin\sh symlink workaround only moves you from a spawn error to a Maven error. Overriding the task in tasks.json works because it skips module detection entirely.
I can open a separate issue for this part if that's easier to track.
Activity
playdohface commentedon Oct 4, 2025
I had a similar issue because I am using fish as my default shell and fixed it with #93 but I am not sure this is going to translate for Windows (it still expects to find a POSIX-shell at
/bin/sh).I'd generally like to make these runnable scripts a bit more robust than what they are, and the user should probably also get an opportunity to configure them, but I'm not quite sure what the best approach would be to doing so - my first instinct was to have proper scripts in the extension folder and publish them via ENV-vars. Maybe someone has a better idea?
Komposten commentedon Oct 5, 2025
I saw your PR but didn't comment on it because I didn't want to risk it being delayed (merging it as-is as opposed to waiting until a platform-agnostic solution is in place).
Setting up platform-specific scripts and then using them depending on platform could be a way, but I don't know if that is possible to configure at the moment?
playdohface commentedon Oct 5, 2025
There is actually a workaround that I found:
if you create a
tasks.jsonin yourproject_root/.zed/directory you can (re-)define the tasks on a per-project basis using any command you like, and zed will prioritize them over the ones provided by the extension.So specifically:
create a file
tasks.jsonin the.zed-directory with a list of TaskTemplates (the best documentation I found for how they work isin the Zed source codein the docs), here's an example:[ { "label": "Custom Run Test $ZED_CUSTOM_java_class_name.$ZED_CUSTOM_java_method_name", "command": "mvn test -Dtest=$ZED_CUSTOM_java_class_name#$ZED_CUSTOM_java_method_name", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-method"] } ]I don't quite understand when zed will refresh these, I had to sometimes run them manually from the
Run>Spawn Task-modal (they will show up if your cursor is at a relevant spot, e.g. a test method)The
labelproperty and thecommandcan be whatever you want and the command will default to your default shell running from your project root directory.The
tagsis the magic ingredient and they will have to match the tags we set in our runnables.scm.Currently they are few and self-explanatory:
java-mainjava-test-methodjava-test-classand you can use these captures as environment-vars:
ZED_CUSTOM_java_package_nameZED_CUSTOM_java_class_nameZED_CUSTOM_java_method_name(plus a bunch more that Zed provides by default but tend to not be relevant for running scripts).
I think other than that, besides providing best-effort defaults we should just document how to do this and encourage people to bring their own tasks until zed-industries/zed#17462 gets some attention.
Komposten commentedon Oct 5, 2025
Weird, that was one of the first things I tested after I first tried to use the runnable, and that time it refused to work. As soon as I added anything with a
$to the task command it wouldn't show up anywhere.But I just tried overriding with a custom task again and now it seems to work perfectly. 🤔
playdohface commentedon Oct 5, 2025
That's likely to do with zed-industries/zed#23275 . If you don't get all your vars right, zed will just pretend your script doesn't exist 🙈
imblowsnow commentedon Oct 7, 2025
same problem @playdohface
CharlesIsMeee commentedon Oct 15, 2025
一个临时凑合的办法,首先把你的默认终端设置为powershell
然后打开 C:\Users\你的用户名\AppData\Local\Zed\extensions\installed\java\languages\java 下的 tasks.json文件
将task文件内容改为
[ { "label": "Run $ZED_CUSTOM_java_class_name", "command": "if (Test-Path 'pom.xml') { mvn clean compile exec:java '-Dexec.mainClass=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew run '-PmainClass=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-main"] }, { "label": "Test $ZED_CUSTOM_java_class_name.$ZED_CUSTOM_java_method_name", "command": "if (Test-Path 'pom.xml') { mvn clean test '-Dtest=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name#ZED_CUSTOM_java_method_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew test --tests '$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name.ZED_CUSTOM_java_method_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-method"] }, { "label": "Test class $ZED_CUSTOM_java_class_name", "command": "if (Test-Path 'pom.xml') { mvn clean compile test '-Dtest=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew test --test '$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-class"] }, { "label": "Run tests", "command": "if (Test-Path 'pom.xml') { mvn clean test } elseif ( Test-Path 'gradlew' ) { ./gradlew test } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always" } ]由于我本人只测试了maven,且我环境变量PATH里配置了mvn,所以如果不行的话需要根据自己的实际情况稍作修改
tianxing-ovo commentedon Nov 28, 2025
需要修改tasks.json
prashanth057 commentedon Feb 21, 2026
Your suggested work around doesnt work for multi maven module project. Are there other zed custome variables to detect the root of the sub modules when trying to execute specific test class of a sub modules?
Radiant303 commentedon May 3, 2026
I am using Zed to run JUnit tests in a Maven Java project.
Running the whole test class works correctly. For example, when I run
UserServiceTest, Maven successfully finds and runs the test method, and the output shows:Tests run: 1, Failures: 0, Errors: 0, Skipped: 0However, when I try to run a single test method from Zed, Maven does not execute any test. The output shows:
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0The problem appears to be in Zed’s
tasks.jsonconfiguration for running a single test method.The generated Maven command is:
mvn clean test '-Dtest=com.javaweb.UserServiceTest#ZED_CUSTOM_java_method_name'But it should be:
mvn clean test '-Dtest=com.javaweb.UserServiceTest#testIsValidUsername'In
tasks.json, the method name variable is missing the$symbol.The incorrect configuration is:
#ZED_CUSTOM_java_method_nameThe correct configuration should be:
#$ZED_CUSTOM_java_method_nameBecause of this typo, Maven tries to run a method literally named
ZED_CUSTOM_java_method_name, which does not exist. As a result, no test method is executed.The complete tasks.json is as follows
[ { "label": "Run $ZED_CUSTOM_java_class_name", "command": "if (Test-Path 'pom.xml') { mvn clean compile exec:java '-Dexec.mainClass=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew run '-PmainClass=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-main"] }, { "label": "Test $ZED_CUSTOM_java_class_name.$ZED_CUSTOM_java_method_name", "command": "if (Test-Path 'pom.xml') { mvn clean test '-Dtest=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name#$ZED_CUSTOM_java_method_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew test --tests '$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name.ZED_CUSTOM_java_method_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-method"] }, { "label": "Test class $ZED_CUSTOM_java_class_name", "command": "if (Test-Path 'pom.xml') { mvn clean compile test '-Dtest=$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } elseif ( Test-Path 'gradlew' ) { ./gradlew test --test '$ZED_CUSTOM_java_package_name.$ZED_CUSTOM_java_class_name' } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always", "tags": ["java-test-class"] }, { "label": "Run tests", "command": "if (Test-Path 'pom.xml') { mvn clean test } elseif ( Test-Path 'gradlew' ) { ./gradlew test } else { echo 'No build system found'}", "use_new_terminal": false, "reveal": "always" } ]aiysya commentedon Jun 16, 2026
I encountered the same problem
error info:
&: The term '/bin/sh' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
⏵ Task
Run GenieAdminApplicationfinished with exit code: 1⏵ Command: /bin/sh -i -c 'pkg="com.XX"; cls="XXXApplication"; if [ -n "$pkg" ]; then c="$pkg.$cls"; else c="$cls"; fi; f="D:\code\XXX\XXXApplication.java"; p="$PWD"; d=$(dirname "${f#$p/}"); if [ -f pom.xml ]; then m="."; md="$d"; while [ "$md" != "." ] && [ "$md" != "/" ]; do if [ -f "$md/pom.xml" ]; then m="$md"; break; fi; md=$(dirname "$md"); done; [ -f ./mvnw ] && CMD="./mvnw" || CMD="mvn"; case "$f" in "/src/test/") COMPILE_GOAL="test-compile"; CLASSPATH_SCOPE="test";; ) COMPILE_GOAL="compile"; CLASSPATH_SCOPE="runtime";; esac; if [ "$m" = "." ]; then $CMD clean $COMPILE_GOAL exec:java -Dexec.mainClass="$c" -Dexec.classpathScope=$CLASSPATH_SCOPE; else $CMD clean $COMPILE_GOAL -pl "$m" -am && $CMD exec:java -pl "$m" -Dexec.mainClass="$c" -Dexec.classpathScope=$CLASSPATH_SCOPE; fi; elif [ -f build.gradle ] || [ -f build.gradle.kts ] || [ -f settings.gradle ] || [ -f settings.gradle.kts ]; then m="."; md="$d"; while [ "$md" != "." ] && [ "$md" != "/" ]; do if [ -f "$md/build.gradle" ] || [ -f "$md/build.gradle.kts" ]; then m="$md"; break; fi; md=$(dirname "$md"); done; if [ "$m" = "." ]; then mp=""; else mp=":$(echo "$m" | tr '/' ':')"; fi; [ -f ./gradlew ] && CMD="./gradlew" || CMD="gradle"; $CMD ${mp}:run -PmainClass="$c"; else find . -name '.java' -not -path './bin/' -not -path './target/' -not -path './build/*' -print0 | xargs -0 javac -d bin && java -cp bin "$c"; fi;'
version ,zed 1.6.3
java extensions 6.8.20
Radiant303 commentedon Jun 16, 2026
You should edit a .settings file in the project root directory.
playdohface commentedon Jun 16, 2026
By the way, there is another alternative fix for this: you can symlink
/bin/shto to Git Bash or another unix-shell emulator (provided that you have one installed):Disclaimer: I haven't tried this as I don't have a Windows environment
DevNiiNartey commentedon Jul 28, 2026
Still reproducing on Zed 1.12.0 (Windows 11), Java extension 6.8.21 — same root cause, but via the
Run <class>task rather than a test runnable:All four task definitions in
languages/java/tasks.jsonpin:and the command bodies are POSIX scripts (
[ -f pom.xml ],$(dirname ...),find ... -print0 | xargs -0). On a stock Windows install there is no/bin/shto spawn at all, so it fails at process creation rather than at PowerShell parse time — the variant in the original report above.Noting for anyone landing here before #252 ships (
mainstill has 5/bin/shoccurrences as of v6.8.24): a user-leveltasks.jsonis a workable stopgap on Windows for the no-build-tool case, using JDK 11+'s single-file source launcher:[ { "label": "Java: run current file", "command": "java \"$ZED_FILE\"", "tags": ["java-main"], "reveal": "always", "use_new_terminal": false, "shell": { "with_arguments": { "program": "powershell.exe", "args": ["-NoProfile"] } } } ]One gotcha that cost me a round trip and may be worth documenting: Zed appends its own shell flag (
-Con Windows,-i -con POSIX) after theargsyou supply. Putting-Commandinargsyieldsand PowerShell then tries to execute
-Cas a cmdlet (CommandNotFoundException). The command flag must be omitted fromargs.tartarughina commentedon Jul 29, 2026
@DevNiiNartey I need to be the bearer of bad news but #252 won't be included in the main release.
While an improvement in terms of feature and DevEx it goes against the original design for tasks envisioned by Zed's team.
While we wait for a redesign to support Win/Unix systems overriding is the only solution.
isacgalvao commentedon Sep 1, 2026
Still reproducing on 6.8.26, Windows 11. There is a second bug hiding behind the shell one, and fixing
/bin/shalone won't be enough.To test, I ran the
java-maintask script under Git Bash'ssh.exe. That gets past the spawn failure, but the module detection still produces an invalid Maven invocation. The script does:On Windows,
$ZED_FILEis a backslash path (C:\Users\me\myproject\...\App.java) while$PWDin a POSIX shell is/c/Users/me/myproject, so the prefix strip never matches.dstays absolute, the walk-up loop finds the rootpom.xml, andmends up as the absolute project root instead of.:Maven rejects that, since
-plexpects a path relative to the reactor. This is a single-module project withpom.xmlat the worktree root, where the expected result ism=".".The module detection came in with #244, so this part postdates the original report here. It may also be what @prashanth057 hit above with multi-module projects.
Practical consequence: the
C:\bin\shsymlink workaround only moves you from a spawn error to a Maven error. Overriding the task intasks.jsonworks because it skips module detection entirely.I can open a separate issue for this part if that's easier to track.
tartarughina commentedon Sep 1, 2026
@isacgalvao if the issue you surfaced is only reproducible in Windows I'd keep it here.
If instead the issue affects Unix systems as well then creating a new issue is the better way forward.