{"record":{"id":"8784a83c4a9c3a1e","repo":"jenkinsci/jenkins","slug":"can-not-call-launchchannel-on-a-dummy-launcher","errorCode":null,"errorMessage":"Can not call launchChannel on a dummy launcher.","messagePattern":"Can not call launchChannel on a dummy launcher\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/Launcher.java","lineNumber":1078,"sourceCode":"            };\n        }\n    }\n\n    @Restricted(NoExternalUse.class)\n    public static class DummyLauncher extends Launcher {\n\n        public DummyLauncher(@NonNull TaskListener listener) {\n            super(listener, null);\n        }\n\n        @Override\n        public Proc launch(ProcStarter starter) throws IOException {\n            throw new IOException(\"Can not call launch on a dummy launcher.\");\n        }\n\n        @Override\n        public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map<String, String> envVars) throws IOException, InterruptedException {\n            throw new IOException(\"Can not call launchChannel on a dummy launcher.\");\n        }\n\n        @Override\n        public void kill(Map<String, String> modelEnvVars) throws IOException, InterruptedException {\n            // Kill method should do nothing.\n        }\n    }\n\n\n    /**\n     * Launches processes remotely by using the given channel.\n     */\n    public static class RemoteLauncher extends Launcher {\n        private final boolean isUnix;\n\n        public RemoteLauncher(@NonNull TaskListener listener, @NonNull VirtualChannel channel, boolean isUnix) {\n            super(listener, channel);\n            this.isUnix = isUnix;","sourceCodeStart":1060,"sourceCodeEnd":1096,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/Launcher.java#L1060-L1096","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nChannel ch = launcher.launchChannel(cmd, out, workDir, env);\n\n// after\nif (launcher instanceof Launcher.DummyLauncher) {\n    throw new IllegalStateException(\"Cannot launch channel without a real agent.\");\n}\nChannel ch = launcher.launchChannel(cmd, out, workDir, env);","handlingStrategy":"type-guard","validationCode":"if (launcher instanceof Launcher.DummyLauncher) {\n    throw new IllegalStateException(\"Cannot launch channel: no real agent.\");\n}","typeGuard":"public static boolean canLaunchChannel(Launcher l) {\n    return !(l instanceof Launcher.DummyLauncher);\n}","tryCatchPattern":"try {\n    Channel ch = launcher.launchChannel(cmd, out, workDir, env);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"dummy launcher\")) {\n        throw new IllegalStateException(\"No channel available; provide a real Launcher\", e);\n    }\n    throw e;\n}","preventionTips":["Obtain a Launcher from an active Computer with a connected channel before calling launchChannel.","Avoid calling launchChannel in controller-only or test contexts."],"tags":["launcher","remoting","channel","dummy"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}