basecamp/kamal · error · ArgumentError
Raw is not compatible with #{incompatible_options.join(" or
Error message
Raw is not compatible with #{incompatible_options.join(" or ")} What it means
`kamal app exec CMD` supports --raw to emit unmodified stdout suitable for piping. Raw capture requires a non-interactive, attached execution, so it cannot be combined with -i/--interactive (TTY session mangles output) or --detach (output goes to container logs, not stdout). Kamal checks this after the detach check and raises ArgumentError naming the conflicting flags.
Source
Thrown at lib/kamal/cli/app.rb:105
puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).info), quiet: quiet
end
end
desc "exec [CMD...]", "Execute a custom command on servers within the app container (use --help to show options)"
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
option :env, aliases: "-e", type: :hash, desc: "Set environment variables for the command"
option :detach, type: :boolean, default: false, desc: "Execute command in a detached container"
option :raw, type: :boolean, default: false, desc: "Output raw, unmodified stdout"
def exec(*cmd)
raw = options[:raw]
if (incompatible_options = [ :interactive, :reuse ].select { |key| options[:detach] && options[key] }.presence)
raise ArgumentError, "Detach is not compatible with #{incompatible_options.join(" or ")}"
end
if raw && (incompatible_options = [ :interactive, :detach ].select { |key| options[key] }.presence)
raise ArgumentError, "Raw is not compatible with #{incompatible_options.join(" or ")}"
end
if cmd.empty?
raise ArgumentError, "No command provided. You must specify a command to execute."
end
with_raw_output(raw) do
pre_connect_if_required
cmd = Kamal::Utils.join_commands(cmd)
env = options[:env]
detach = options[:detach]
quiet = options[:quiet]
case
when options[:interactive] && options[:reuse]
say "Get current version of running container...", :magenta unless options[:version]
using_version(options[:version] || current_running_version) do |version|
say "Launching interactive command with version #{version} via SSH from existing container on #{KAMAL.primary_host}...", :magentaView on GitHub (pinned to eee0083b38)
Solutions
- Remove -i or --detach: `kamal app exec --raw CMD` alone is the supported way to get clean output.
- For a detached command's output, read it afterwards with `kamal app logs` or `docker logs`.
- For an interactive shell, drop --raw: `kamal app exec -i bash`.
Example fix
# before kamal app exec --raw -i rails console # after kamal app exec -i rails console # or for scriptable, clean stdout: kamal app exec --reuse --raw rails runner 'puts User.count'
Defensive patterns
Strategy: validation
Validate before calling
raw, interactive, detach = ARGV.any? { |a| a == "--raw" }, ARGV.include?("-i"), ARGV.include?("--detach")
abort "--raw cannot combine with -i/--interactive or --detach" if raw && (interactive || detach) Try / catch
begin
Kamal::CLI::App.new.invoke(:exec, [ "rails", "runner", "puts 1" ], raw: true, reuse: true)
rescue ArgumentError => e
warn "flag conflict: #{e.message}" if e.message.start_with?("Raw is not compatible")
end Prevention
- Reserve --raw for scripted stdout capture of non-interactive, non-detached commands.
- Read detached output via `kamal app logs`/`docker logs` instead of trying to capture it at exec time.
When it happens
Trigger: `kamal app exec --raw -i bash`, `kamal app exec --raw --detach rails runner script.rb`, or any invocation where options[:raw] is truthy together with options[:interactive] or options[:detach].
Common situations: Piping a command's output into jq/grep with --raw while leaving -i on the line from earlier console use; adding --raw to a detached job expecting to capture logs; aliases that combine flags for convenience.
Related errors
- Detach is not compatible with #{incompatible_options.join("
- Raw is not compatible with interactive
- No command provided. You must specify a command to execute.
- Raw is not compatible with interactive
- 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/3c55b7d908a8c065.
Report an issue: GitHub.