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

  1. Pass -f/--force when overwriting is intended: fpm -f -p dist/app.deb ...
  2. Clean the output dir in the build script (rm -f dist/*.deb) for reproducible rebuilds
  3. 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

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


AI-assisted analysis of jordansissel/fpm@b6d77ba72a (2026-08-21). Data as JSON: /api/errors/2d8d1cc1eeeb770e. Report an issue: GitHub.