{"record":{"id":"b346da0f5fa89287","repo":"jordansissel/fpm","slug":"parent-directory-does-not-exist-file-dirname-ou","errorCode":null,"errorMessage":"Parent directory does not exist: #{File.dirname(output_path)} - cannot write to #{output_path}","messagePattern":"Parent directory does not exist: #(.+?) - cannot write to #(.+?)","errorType":"validation","errorClass":"FPM::Package::ParentDirectoryMissing","httpStatus":null,"severity":"error","filePath":"lib/fpm/package.rb","lineNumber":532,"sourceCode":"\n  # Get the contents of the script by a given name.\n  #\n  # If template_scripts? is set in attributes (often by the --template-scripts\n  # flag), then apply it as an ERB template.\n  def script(script_name)\n    if attributes[:template_scripts?]\n      erb = erbnew(scripts[script_name])\n      # TODO(sissel): find the original file name for the file.\n      erb.filename = \"script(#{script_name})\"\n      return erb.result(binding)\n    else\n      return scripts[script_name]\n    end\n  end # def script\n\n  def output_check(output_path)\n    if !File.directory?(File.dirname(output_path))\n      raise ParentDirectoryMissing.new(output_path)\n    end\n    if File.file?(output_path)\n      if attributes[:force?]\n        logger.warn(\"Force flag given. Overwriting package at #{output_path}\")\n        File.delete(output_path)\n      else\n        raise FileAlreadyExists.new(output_path)\n      end\n    end\n  end # def output_path\n\n  def provides=(value)\n    if !value.is_a?(Array)\n      @provides = [value]\n    else\n      @provides = value\n    end\n  end # def provides=","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/jordansissel/fpm/blob/b6d77ba72a560b687723376a0e5115c3a92634ad/lib/fpm/package.rb#L514-L550","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create the directory in the build script first: mkdir -p $(dirname <output-path>)","Check the -p/--package value for typos and prefer absolute paths so cwd changes cannot redirect output","API: FileUtils.mkdir_p(File.dirname(path)) before pkg.output(path)"],"exampleFix":"# before\nfpm -s dir -t deb -p dist/app_1.0_amd64.deb ./app   # dist/ missing => ParentDirectoryMissing\n\n# after\nmkdir -p dist && fpm -s dir -t deb -p dist/app_1.0_amd64.deb ./app","handlingStrategy":"validation","validationCode":"require 'fileutils'\n\nout = File.expand_path('dist/app_1.0_amd64.deb')\nFileUtils.mkdir_p(File.dirname(out))\nsystem('fpm', '-s', 'dir', '-t', 'deb', '-p', out, './app')","typeGuard":null,"tryCatchPattern":"begin\n  pkg.output(out)\nrescue FPM::Package::ParentDirectoryMissing => e\n  FileUtils.mkdir_p(File.dirname(out))\n  pkg.output(out)\nend","preventionTips":["mkdir -p the output directory in the build script before invoking fpm","Prefer absolute -p paths so cwd changes cannot redirect output","Create dist/artifacts directories during CI workspace setup, not as an afterthought"],"tags":["fpm","filesystem","output-path","packaging"],"backgroundTag":"missing-output-directory","analyzedSha":"b6d77ba72a560b687723376a0e5115c3a92634ad","analyzedAt":"2026-08-21T16:39:02.570Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}