{"record":{"id":"17ba160c7eb9ed71","repo":"puppetlabs/puppet","slug":"execution-of-config-version-command-cmd-faile","errorCode":null,"errorMessage":"Execution of config_version command `%{cmd}` failed: %{message}","messagePattern":"Execution of config_version command `%(.+?)` failed: %(.+?)","errorType":"exception","errorClass":"Puppet::ParseError","httpStatus":null,"severity":"error","filePath":"lib/puppet/resource/type_collection.rb","lineNumber":181,"sourceCode":"    end\n  end\n\n  def parse_failed?\n    @parse_failed\n  end\n\n  def version\n    unless defined?(@version)\n      if environment.config_version.nil? || environment.config_version == \"\"\n        @version = Time.now.to_i\n      else\n        @version = Puppet::Util::Execution.execute([environment.config_version]).to_s.strip\n      end\n    end\n\n    @version\n  rescue Puppet::ExecutionFailure => e\n    raise Puppet::ParseError, _(\"Execution of config_version command `%{cmd}` failed: %{message}\") % { cmd: environment.config_version, message: e.message }, e.backtrace\n  end\n\n  private\n\n  COLON_COLON = \"::\"\n\n  # Resolve namespaces and find the given object.  Autoload it if\n  # necessary.\n  def find_or_load(name, type)\n    # always lock the environment before locking the type collection\n    @environment.lock.synchronize do\n      @lock.synchronize do\n        # Name is always absolute, but may start with :: which must be removed\n        fqname = (name[0, 2] == COLON_COLON ? name[2..] : name)\n\n        result = send(type, fqname)\n        unless result\n          if @notfound[fqname] && Puppet[:ignoremissingtypes]","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/resource/type_collection.rb#L163-L199","documentation":"EnvironmentConfig's TypeCollection#version executes the command from the environment's config_version setting (environment.conf or puppet.conf) on every catalog compile to stamp the report with a version string. If Puppet::Util::Execution.execute fails (non-zero exit, missing command), the Puppet::ExecutionFailure is wrapped in Puppet::ParseError including the command and its error output, and compilation aborts.","triggerScenarios":"config_version = /usr/local/bin/git-version.sh where the script is missing, not executable, has a bad shebang, or exits non-zero; a `git rev-parse HEAD` hook run outside the git repo; permission denied when the puppet user cannot read the repo; command not on the PATH of the service.","commonSituations":"Git-based deployment hooks (`config_version=/usr/bin/git --git-dir ... rev-parse HEAD`); scripts that assume a login shell PATH or environment variables; moving environments to a new server without the hook's dependencies.","solutions":["Run the exact command string manually as the puppet service user and fix whatever makes it fail (executable bit, shebang, permissions).","Make the script failure-proof: fall back internally, e.g. `git rev-parse --short HEAD 2>/dev/null || date +%s`, so it always exits 0.","Use an absolute path for the command and avoid relying on PATH.","If the hook is not needed, blank or remove the config_version setting — version falls back to the compile timestamp (Time.now.to_i)."],"exampleFix":"# environment.conf — before\nconfig_version=/usr/local/bin/git-version.sh\n# git-version.sh: #!/bin/sh\\ngit rev-parse --short HEAD   # fails outside a repo\n\n# after — script always succeeds\n#!/bin/sh\\ncd /etc/puppetlabs/code/environments/production || exit 1\\ngit rev-parse --short HEAD 2>/dev/null || date +%s","handlingStrategy":"try-catch","validationCode":"# smoke-test the hook before relying on it\ncmd = environment.config_version\nexitstatus = Puppet::Util::Execution.execute([cmd], failonfail: false).exitstatus if cmd && !cmd.empty?\nraise ArgumentError, \"config_version hook broken (exit #{exitstatus})\" if exitstatus && !exitstatus.zero?","typeGuard":null,"tryCatchPattern":"begin\n  version = type_collection.version\nrescue Puppet::ParseError => e\n  raise unless e.message.include?('config_version')\n  Puppet.warning(\"config_version failed (#{e.message}); using timestamp\")\n  version = Time.now.to_i\nend","preventionTips":["Make config_version scripts infallible (internal fallback to `date +%s`, always exit 0)","Use absolute paths and no PATH/shell assumptions in the hook command","Run the hook manually as the puppet service user after every environment deployment"],"tags":["puppet","environment","config-version","execution-failure","parse-error"],"backgroundTag":"config-hook-script-failure","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}