From 948910fc8795cb58303beff199ea1764b4307b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=C5=81uszczek?= Date: Sun, 22 Mar 2026 13:11:18 +0100 Subject: [PATCH] Fix missing endpointId query param in WebSocket exec URL Portainer requires endpointId in the websocket/exec query string. Was returning 400 "Missing query parameter". Co-Authored-By: Claude Sonnet 4.6 --- lib/portainer_cli/commands/console.rb | 6 +++--- lib/portainer_cli/commands/exec.rb | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/portainer_cli/commands/console.rb b/lib/portainer_cli/commands/console.rb index 108a6ef..2d041b0 100644 --- a/lib/portainer_cli/commands/console.rb +++ b/lib/portainer_cli/commands/console.rb @@ -38,7 +38,7 @@ module PortainerCli $stderr.puts dim("Connecting to #{container_name} (#{container_id[0, 12]})...") exec_id = create_exec(endpoint_id, container_id, opts[:shell]) - ws_url = exec_websocket_url(exec_id) + ws_url = exec_websocket_url(exec_id, endpoint_id) send_resize(endpoint_id, exec_id) if $stdout.tty? trap('SIGWINCH') { send_resize(endpoint_id, exec_id) } if $stdout.tty? @@ -125,9 +125,9 @@ module PortainerCli result['Id'] end - def exec_websocket_url(exec_id) + def exec_websocket_url(exec_id, endpoint_id) token = @config.token || @config.api_key - @client.websocket_url('/api/websocket/exec', token: token, id: exec_id) + @client.websocket_url('/api/websocket/exec', token: token, id: exec_id, endpointId: endpoint_id) end def send_resize(endpoint_id, exec_id) diff --git a/lib/portainer_cli/commands/exec.rb b/lib/portainer_cli/commands/exec.rb index a63de90..f429bf8 100644 --- a/lib/portainer_cli/commands/exec.rb +++ b/lib/portainer_cli/commands/exec.rb @@ -32,7 +32,7 @@ module PortainerCli $stderr.puts dim("Connecting to #{container_name} (#{container_id[0, 12]})...") exec_id = create_exec(endpoint_id, container_id, opts[:shell]) - ws_url = exec_websocket_url(exec_id) + ws_url = exec_websocket_url(exec_id, endpoint_id) send_resize(endpoint_id, exec_id) if $stdout.tty? trap('SIGWINCH') { send_resize(endpoint_id, exec_id) } if $stdout.tty? @@ -78,10 +78,9 @@ module PortainerCli result['Id'] end - def exec_websocket_url(exec_id) - # Portainer uses JWT for websocket auth (not API key), so we need to include token in query + def exec_websocket_url(exec_id, endpoint_id) token = @config.token || @config.api_key - @client.websocket_url('/api/websocket/exec', token: token, id: exec_id) + @client.websocket_url('/api/websocket/exec', token: token, id: exec_id, endpointId: endpoint_id) end def send_resize(endpoint_id, exec_id)