jenkinsci/jenkins · error · IOException
Can not call launchChannel on a dummy launcher.
Error message
Can not call launchChannel on a dummy launcher.
What it means
DummyLauncher.launchChannel throws IOException because it has no remote channel to connect to — it exists as a type-compliant placeholder Launcher. launchChannel is used to start a remote process and obtain its Channel for remoting. Since DummyLauncher has no underlying transport, this always fails.
Source
Thrown at core/src/main/java/hudson/Launcher.java:1078
};
}
}
@Restricted(NoExternalUse.class)
public static class DummyLauncher extends Launcher {
public DummyLauncher(@NonNull TaskListener listener) {
super(listener, null);
}
@Override
public Proc launch(ProcStarter starter) throws IOException {
throw new IOException("Can not call launch on a dummy launcher.");
}
@Override
public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map<String, String> envVars) throws IOException, InterruptedException {
throw new IOException("Can not call launchChannel on a dummy launcher.");
}
@Override
public void kill(Map<String, String> modelEnvVars) throws IOException, InterruptedException {
// Kill method should do nothing.
}
}
/**
* Launches processes remotely by using the given channel.
*/
public static class RemoteLauncher extends Launcher {
private final boolean isUnix;
public RemoteLauncher(@NonNull TaskListener listener, @NonNull VirtualChannel channel, boolean isUnix) {
super(listener, channel);
this.isUnix = isUnix;View on GitHub (pinned to 2e228ff40b)
Solutions
- Obtain a real Launcher from a Computer that has an active channel before calling launchChannel.
- In tests, use a real Channel/Launcher setup or mock launchChannel appropriately.
- Guard with an instanceof check against Launcher.DummyLauncher.
Example fix
// before
Channel ch = launcher.launchChannel(cmd, out, workDir, env);
// after
if (launcher instanceof Launcher.DummyLauncher) {
throw new IllegalStateException("Cannot launch channel without a real agent.");
}
Channel ch = launcher.launchChannel(cmd, out, workDir, env); Defensive patterns
Strategy: type-guard
Validate before calling
if (launcher instanceof Launcher.DummyLauncher) {
throw new IllegalStateException("Cannot launch channel: no real agent.");
} Type guard
public static boolean canLaunchChannel(Launcher l) {
return !(l instanceof Launcher.DummyLauncher);
} Try / catch
try {
Channel ch = launcher.launchChannel(cmd, out, workDir, env);
} catch (IOException e) {
if (e.getMessage().contains("dummy launcher")) {
throw new IllegalStateException("No channel available; provide a real Launcher", e);
}
throw e;
} Prevention
- Obtain a Launcher from an active Computer with a connected channel before calling launchChannel.
- Avoid calling launchChannel in controller-only or test contexts.
When it happens
Trigger: Code calls Launcher.launchChannel(String[], OutputStream, FilePath, Map) on a DummyLauncher — typically during remoting setup or a plugin that tries to establish a channel to a process that doesn't exist.
Common situations: Plugin code or pipeline infrastructure attempting to establish a remoting channel in a context where the Launcher is a DummyLauncher (controller-only execution, test harness without a real agent).
Related errors
- Can not call launch on a dummy launcher.
- Failed to join the process
- Failed to retrieve command result in time: {}
- Failed to unpack %s (%d bytes read)
- remote file operation failed
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/8784a83c4a9c3a1e.
Report an issue: GitHub.