jordansissel/fpm · error · FPM::Package::FileAlreadyExists
File already exists, refusing to continue: #{output_path}
Error message
File already exists, refusing to continue: #{output_path} What it means
The second half of output_check: if the target package file already exists and --force was not given, FileAlreadyExists is raised instead of silently overwriting. This protects previously built artifacts; with attributes[:force?] (the -f flag) fpm logs a warning and deletes the file before rebuilding.
Source
Thrown at lib/fpm/package.rb:539
erb = erbnew(scripts[script_name])
# TODO(sissel): find the original file name for the file.
erb.filename = "script(#{script_name})"
return erb.result(binding)
else
return scripts[script_name]
end
end # def script
def output_check(output_path)
if !File.directory?(File.dirname(output_path))
raise ParentDirectoryMissing.new(output_path)
end
if File.file?(output_path)
if attributes[:force?]
logger.warn("Force flag given. Overwriting package at #{output_path}")
File.delete(output_path)
else
raise FileAlreadyExists.new(output_path)
end
end
end # def output_path
def provides=(value)
if !value.is_a?(Array)
@provides = [value]
else
@provides = value
end
end # def provides=
# General public API
public(:type, :initialize, :convert, :input, :output, :to_s, :cleanup, :files,
:version, :script, :provides=)
# Package internal public api
public(:cleanup_staging, :cleanup_build, :staging_path, :converted_from,View on GitHub (pinned to b6d77ba72a)
Solutions
- Pass -f/--force when overwriting is intended: fpm -f -p dist/app.deb ...
- Clean the output dir in the build script (rm -f dist/*.deb) for reproducible rebuilds
- Bump --iteration or embed a git SHA/timestamp in the -p filename so builds never collide
Example fix
# before fpm -s dir -t deb -p dist/app_1.0_amd64.deb ./app # file left by previous build # after fpm -s dir -t deb -f -p dist/app_1.0_amd64.deb ./app
Defensive patterns
Strategy: validation
Validate before calling
out = File.expand_path('dist/app_1.0_amd64.deb')
File.delete(out) if File.exist?(out) # or pass -f / attributes[:force?] = true
system('fpm', '-s', 'dir', '-t', 'deb', '-p', out, './app') Try / catch
begin
pkg.output(out)
rescue FPM::Package::FileAlreadyExists
warn "#{out} exists; bump --iteration or pass --force"
raise
end Prevention
- Make rebuilds idempotent: rm -f dist/* before fpm, or always pass -f in CI
- Include build numbers or git SHAs in output filenames to avoid collisions
- Treat an unexpected FileAlreadyExists as a signal that version/iteration was not bumped
When it happens
Trigger: Rebuilding the same name/version/iteration to the same -p path (default output filenames include the version, so unchanged versions collide); CI re-runs without workspace cleanup; API pkg.output(path) without setting attributes[:force?].
Common situations: Iterating locally on the same unreleased version; CI retrying a job into a dirty workspace; artifacts directory shared between matrix jobs writing identical filenames.
Related errors
- Parent directory does not exist: #{File.dirname(output_path)
- '#{editor}' failed (exit code #{$?.exitstatus}) Full command
- File is device which fpm doesn't know how to copy (#{File.ft
- #{self.class.name} does not yet support reading #{self.type}
- #{self.class.name} does not yet support creating #{self.type
AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21).
Data as JSON: /api/errors/2d8d1cc1eeeb770e.
Report an issue: GitHub.