{"record":{"id":"3c55b7d908a8c065","repo":"basecamp/kamal","slug":"raw-is-not-compatible-with-incompatible-options","errorCode":null,"errorMessage":"Raw is not compatible with #{incompatible_options.join(\" or \")}","messagePattern":"Raw is not compatible with #(.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/kamal/cli/app.rb","lineNumber":105,"sourceCode":"      puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).info), quiet: quiet\n    end\n  end\n\n  desc \"exec [CMD...]\", \"Execute a custom command on servers within the app container (use --help to show options)\"\n  option :interactive, aliases: \"-i\", type: :boolean, default: false, desc: \"Execute command over ssh for an interactive shell (use for console/bash)\"\n  option :reuse, type: :boolean, default: false, desc: \"Reuse currently running container instead of starting a new one\"\n  option :env, aliases: \"-e\", type: :hash, desc: \"Set environment variables for the command\"\n  option :detach, type: :boolean, default: false, desc: \"Execute command in a detached container\"\n  option :raw, type: :boolean, default: false, desc: \"Output raw, unmodified stdout\"\n  def exec(*cmd)\n    raw = options[:raw]\n\n    if (incompatible_options = [ :interactive, :reuse ].select { |key| options[:detach] && options[key] }.presence)\n      raise ArgumentError, \"Detach is not compatible with #{incompatible_options.join(\" or \")}\"\n    end\n\n    if raw && (incompatible_options = [ :interactive, :detach ].select { |key| options[key] }.presence)\n      raise ArgumentError, \"Raw is not compatible with #{incompatible_options.join(\" or \")}\"\n    end\n\n    if cmd.empty?\n      raise ArgumentError, \"No command provided. You must specify a command to execute.\"\n    end\n\n    with_raw_output(raw) do\n      pre_connect_if_required\n\n      cmd = Kamal::Utils.join_commands(cmd)\n      env = options[:env]\n      detach = options[:detach]\n      quiet = options[:quiet]\n      case\n      when options[:interactive] && options[:reuse]\n        say \"Get current version of running container...\", :magenta unless options[:version]\n        using_version(options[:version] || current_running_version) do |version|\n          say \"Launching interactive command with version #{version} via SSH from existing container on #{KAMAL.primary_host}...\", :magenta","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/cli/app.rb#L87-L123","documentation":"`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.","triggerScenarios":"`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].","commonSituations":"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.","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`."],"exampleFix":"# before\nkamal app exec --raw -i rails console\n# after\nkamal app exec -i rails console\n# or for scriptable, clean stdout:\nkamal app exec --reuse --raw rails runner 'puts User.count'","handlingStrategy":"validation","validationCode":"raw, interactive, detach = ARGV.any? { |a| a == \"--raw\" }, ARGV.include?(\"-i\"), ARGV.include?(\"--detach\")\nabort \"--raw cannot combine with -i/--interactive or --detach\" if raw && (interactive || detach)","typeGuard":null,"tryCatchPattern":"begin\n  Kamal::CLI::App.new.invoke(:exec, [ \"rails\", \"runner\", \"puts 1\" ], raw: true, reuse: true)\nrescue ArgumentError => e\n  warn \"flag conflict: #{e.message}\" if e.message.start_with?(\"Raw is not compatible\")\nend","preventionTips":["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."],"tags":["kamal","app","exec","cli","argument-conflict","stdout"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}