basecamp/kamal · error · ArgumentError
Raw is not compatible with interactive
Error message
Raw is not compatible with interactive
What it means
`kamal server exec CMD` runs a command directly on the configured hosts over SSH. --raw makes Kamal emit unmodified stdout (pipeable), while -i/--interactive allocates an interactive SSH session on the primary host. Since raw capture and a TTY-attached interactive session are incompatible, Kamal raises ArgumentError immediately when both flags are given, before any connection is made.
Source
Thrown at lib/kamal/cli/server.rb:9
class Kamal::Cli::Server < Kamal::Cli::Base
desc "exec", "Run a custom command on the server (use --help to show options)"
option :interactive, type: :boolean, aliases: "-i", default: false, desc: "Run the command interactively (use for console/bash)"
option :raw, type: :boolean, default: false, desc: "Output raw, unmodified stdout"
def exec(*cmd)
raw = options[:raw]
if raw && options[:interactive]
raise ArgumentError, "Raw is not compatible with interactive"
end
with_raw_output(raw) do
pre_connect_if_required
cmd = Kamal::Utils.join_commands(cmd)
hosts = KAMAL.hosts
quiet = options[:quiet]
case
when options[:interactive]
host = KAMAL.primary_host
say "Running '#{cmd}' on #{host} interactively...", :magenta
run_locally { exec KAMAL.server.run_over_ssh(cmd, host: host) }
else
say "Running '#{cmd}' on #{hosts.join(', ')}...", :magentaView on GitHub (pinned to eee0083b38)
Solutions
- Choose one mode: `kamal server exec -i bash` for an interactive shell, `kamal server exec --raw CMD` for clean machine-readable output.
- Remove --raw from aliases that also set -i (or vice versa).
- For capturing interactive-program output, run the program non-interactively instead.
Example fix
# before kamal server exec --raw -i bash # after kamal server exec -i bash # or kamal server exec --raw 'uptime'
Defensive patterns
Strategy: validation
Validate before calling
raw = ARGV.include?("--raw")
interactive = ARGV.include?("-i") || ARGV.include?("--interactive")
abort "--raw and -i are mutually exclusive" if raw && interactive
system("kamal server exec #{ARGV.join(' ')}") Try / catch
begin
Kamal::CLI::Server.new.invoke(:exec, [ "uptime" ], raw: true)
rescue ArgumentError => e
warn "flag conflict: #{e.message}" if e.message.include?("not compatible")
end Prevention
- Use --raw only for non-interactive scripted commands on servers.
- Keep aliases from bundling -i with capture-style flags.
When it happens
Trigger: `kamal server exec --raw -i bash`, or any invocation where options[:raw] and options[:interactive] are both truthy — commonly a wrapper/alias that always adds one of the flags combined with a manual one-off use of the other.
Common situations: Piping `kamal server exec --raw uptime` into scripts while an alias injects -i; copy-pasted commands mixing console-style flags with capture-style flags; forgetting that --raw only matters for non-interactive output.
Related errors
- Raw is not compatible with interactive
- Detach is not compatible with #{incompatible_options.join("
- Raw is not compatible with #{incompatible_options.join(" or
- No command provided. You must specify a command to execute.
- Deploy lock held manually, not waiting. Run 'kamal lock help
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/8d963755c3ad1c96.
Report an issue: GitHub.