jordansissel/fpm · error · FPM::Util::ExecutableNotFound
#{program}
Error message
#{program} What it means
This is the generic guard inside FPM::Util#execmd (reached via safesystem): any program whose name contains no '/' must be found on PATH, otherwise ExecutableNotFound is raised with the bare program name as the message. Every external tool fpm drives (rpmbuild, dpkg-deb, gem, ar, tar, python, ...) passes through this check.
Source
Thrown at lib/fpm/util.rb:136
raise ArgumentError.new("missing argument: cmd")
end
if i < args.size
if args[i].kind_of?(Hash)
opts = Hash[args[i].map {|k,v| [k.to_sym, v]} ]
i += 1
end
else
opts = Hash[]
end
opts[:process] = false unless opts.include?(:process)
opts[:stdin] = true unless opts.include?(:stdin)
opts[:stdout] = true unless opts.include?(:stdout)
opts[:stderr] = true unless opts.include?(:stderr)
if !program.include?("/") and !program_in_path?(program)
raise ExecutableNotFound.new(program)
end
logger.info("Running command", :args => args2)
stdout_r, stdout_w = IO.pipe
stderr_r, stderr_w = IO.pipe
stdin_r, stdin_w = IO.pipe
pid = Process.spawn(env, *args2, :out => stdout_w, :err => stderr_w, :in => stdin_r)
stdout_w.close; stderr_w.close
logger.debug("Process is running", :pid => pid)
if block_given?
args3 = []
args3.push(process) if opts[:process]
args3.push(stdin_w) if opts[:stdin]
args3.push(stdout_r) if opts[:stdout]
args3.push(stderr_r) if opts[:stderr]View on GitHub (pinned to b6d77ba72a)
Solutions
- Install the tool named in the error message (e.g. apt-get install rpm for rpmbuild) — fpm's README lists per-target dependencies
- Confirm 'which <program>' succeeds under the exact environment fpm runs in (CI container, cron PATH)
- For API use, preflight with FPM::Util.program_in_path?(program) and fail with an actionable message
Example fix
# before fpm -s dir -t rpm ./app # => ExecutableNotFound: rpmbuild # after apt-get install -y rpm && fpm -s dir -t rpm ./app
Defensive patterns
Strategy: validation
Validate before calling
require 'fpm/util'
required = { 'rpm' => %w[rpmbuild rpm], 'deb' => %w[dpkg-deb ar] }
required.fetch(ENV.fetch('FPM_TARGET', 'rpm')).each do |prog|
abort "#{prog} not installed" unless FPM::Util.program_in_path?(prog)
end Try / catch
begin
safesystem('rpmbuild', '-bb', 'app.spec')
rescue FPM::Util::ExecutableNotFound => e
abort "missing tool '#{e.message}'; install the build dependencies for this target type"
end Prevention
- Install the documented per-target build dependencies in your build image
- Preflight every external tool with program_in_path? when using the fpm API, failing with an actionable message
- Run fpm inside the same container/PATH it will be used from in production, not from a richer host shell
When it happens
Trigger: Building RPMs without rpm-build installed (rpmbuild missing); deb targets without dpkg-deb; -t gem without the gem CLI; -s python without a python binary; any API call safesystem('tool', ...) with tool not installed.
Common situations: Build images missing the target format's toolchain; terse one-word errors ('rpmbuild') confusing CI logs; environments where fpm runs under cron/systemd with a stripped PATH.
Related errors
- pear
- '#{editor}' failed (exit code #{$?.exitstatus}) Full command
- #{program} failed (exit code #{exit_code}). Full command was
- The given workdir '#{workdir}' does not exist.
- The given workdir '#{workdir}' must be a directory.
AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21).
Data as JSON: /api/errors/27bb9ac7bae857a5.
Report an issue: GitHub.