{"record":{"id":"76a35e01d91e2fd7","repo":"jordansissel/fpm","slug":"program-failed-exit-code-exit-code-full-c","errorCode":null,"errorMessage":"#{program} failed (exit code #{exit_code}). Full command was:#{args.inspect}","messagePattern":"#(.+?) failed \\(exit code #(.+?)\\)\\. Full command was:#(.+?)","errorType":"exception","errorClass":"FPM::Util::ProcessFailed","httpStatus":null,"severity":"error","filePath":"lib/fpm/util.rb","lineNumber":194,"sourceCode":"  # Run a command safely in a way that gets reports useful errors.\n  def safesystem(*args)\n    # ChildProcess isn't smart enough to run a $SHELL if there's\n    # spaces in the first arg and there's only 1 arg.\n    if args.size == 1\n      args = [ default_shell, \"-c\", args[0] ]\n    end\n\n    if args[0].kind_of?(Hash)\n      env = args.shift()\n      exit_code = execmd(env, args)\n    else\n      exit_code = execmd(args)\n    end\n    program = args[0]\n    success = (exit_code == 0)\n\n    if !success\n      raise ProcessFailed.new(\"#{program} failed (exit code #{exit_code})\" \\\n                              \". Full command was:#{args.inspect}\")\n    end\n    return success\n  end # def safesystem\n\n  # Run a command safely in a way that captures output and status.\n  def safesystemout(*args)\n    if args.size == 1\n      args = [ ENV[\"SHELL\"], \"-c\", args[0] ]\n    end\n    program = args[0]\n\n    if !program.include?(\"/\") and !program_in_path?(program)\n      raise ExecutableNotFound.new(program)\n    end\n\n    stdout_r_str = nil\n    exit_code = execmd(args, :stdin=>false, :stderr=>false) do |stdout|","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/jordansissel/fpm/blob/b6d77ba72a560b687723376a0e5115c3a92634ad/lib/fpm/util.rb#L176-L212","documentation":"FPM::Util.safesystem runs a child process and raises FPM::Util::ProcessFailed when the exit code is non-zero; the message includes the exit code and the full Ruby args array. The real cause was already printed by the failing tool on stderr — this exception is fpm's way of propagating that failure.","triggerScenarios":"rpmbuild rejecting invalid metadata (e.g. a version containing '-'); dpkg-deb failing on unreadable control files; gem build rejecting a malformed gemspec; ar/tar flag incompatibilities on old platforms; the child being killed by a signal.","commonSituations":"Missing or too-old build tools for the target type; --version/--iteration/--depends values that the target tool validates more strictly than fpm; filenames with spaces tripping downstream tools; disk exhaustion during package compression.","solutions":["Re-run with --log debug (or --verbose) to see the exact command, then run that command by hand to read the tool's real error","Fix the metadata the tool complains about (classic: RPM-illegal characters in version/iteration)","Install or upgrade the build tool for the target format in the build image","Check disk space and permissions on the output and TMP directories"],"exampleFix":"# before: '-' is illegal in an RPM version, rpmbuild exits non-zero\nfpm -s dir -t rpm -v 1.0-beta2 -n app ./app\n\n# after\nfpm -s dir -t rpm -v 1.0.beta2 -n app ./app","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  pkg.output(path)\nrescue FPM::Util::ProcessFailed => e\n  warn e.message  # contains exit code and full args; run that command manually for the real error\n  raise\nend","preventionTips":["Re-run with --log debug to capture the exact failing command plus the tool's stderr","Sanitize metadata for the target tool (e.g. no dashes in RPM versions)","Pin modern rpmbuild/dpkg-deb versions in build images to avoid flag and format incompatibilities"],"tags":["fpm","subprocess","exit-code","rpmbuild","build-failure"],"backgroundTag":"subprocess-nonzero-exit","analyzedSha":"b6d77ba72a560b687723376a0e5115c3a92634ad","analyzedAt":"2026-08-21T16:39:02.570Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}