jordansissel/fpm · error · FPM::Package::ParentDirectoryMissing

Parent directory does not exist: #{File.dirname(output_path)

Error message

Parent directory does not exist: #{File.dirname(output_path)} - cannot write to #{output_path}

What it means

FPM::Package#output_check runs before any package file is written: if the parent directory of the requested output path is not a directory, ParentDirectoryMissing is raised. fpm deliberately does not mkdir -p your destination, so '-p dist/foo.deb' fails when dist/ does not exist.

Source

Thrown at lib/fpm/package.rb:532

  # Get the contents of the script by a given name.
  #
  # If template_scripts? is set in attributes (often by the --template-scripts
  # flag), then apply it as an ERB template.
  def script(script_name)
    if attributes[:template_scripts?]
      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=

View on GitHub (pinned to b6d77ba72a)

Solutions

  1. Create the directory in the build script first: mkdir -p $(dirname <output-path>)
  2. Check the -p/--package value for typos and prefer absolute paths so cwd changes cannot redirect output
  3. API: FileUtils.mkdir_p(File.dirname(path)) before pkg.output(path)

Example fix

# before
fpm -s dir -t deb -p dist/app_1.0_amd64.deb ./app   # dist/ missing => ParentDirectoryMissing

# after
mkdir -p dist && fpm -s dir -t deb -p dist/app_1.0_amd64.deb ./app
Defensive patterns

Strategy: validation

Validate before calling

require 'fileutils'

out = File.expand_path('dist/app_1.0_amd64.deb')
FileUtils.mkdir_p(File.dirname(out))
system('fpm', '-s', 'dir', '-t', 'deb', '-p', out, './app')

Try / catch

begin
  pkg.output(out)
rescue FPM::Package::ParentDirectoryMissing => e
  FileUtils.mkdir_p(File.dirname(out))
  pkg.output(out)
end

Prevention

When it happens

Trigger: Running 'fpm -p build/foo.rpm ...' when build/ does not exist; calling pkg.output('newdir/app.deb') via the API with newdir missing; output paths assembled from variables whose directory component was never created; relative -p paths resolved from an unexpected cwd.

Common situations: Fresh clones or CI workspaces where the dist/artifacts directory is gitignored and never created; build scripts that assume fpm creates intermediate directories; typos in the -p path.

Related errors


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