{"record":{"id":"7011e76a417f9327","repo":"puppetlabs/puppet","slug":"paths-must-be-fully-qualified","errorCode":null,"errorMessage":"Paths must be fully qualified","messagePattern":"Paths must be fully qualified","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/file_serving/base.rb","lineNumber":62,"sourceCode":"  end\n\n  # Determine how we deal with links.\n  attr_reader :links\n\n  def links=(value)\n    value = value.to_sym\n    value = :manage if value == :ignore\n    # TRANSLATORS ':link', ':manage', ':follow' should not be translated\n    raise(ArgumentError, _(\":links can only be set to :manage or :follow\")) unless [:manage, :follow].include?(value)\n\n    @links = value\n  end\n\n  # Set our base path.\n  attr_reader :path\n\n  def path=(path)\n    raise ArgumentError, _(\"Paths must be fully qualified\") unless Puppet::FileServing::Base.absolute?(path)\n\n    @path = path\n  end\n\n  # Set a relative path; this is used for recursion, and sets\n  # the file's path relative to the initial recursion point.\n  attr_reader :relative_path\n\n  def relative_path=(path)\n    raise ArgumentError, _(\"Relative paths must not be fully qualified\") if Puppet::FileServing::Base.absolute?(path)\n\n    @relative_path = path\n  end\n\n  # Stat our file, using the appropriate link-sensitive method.\n  def stat\n    @stat_method ||= links == :manage ? :lstat : :stat\n    Puppet::FileSystem.send(@stat_method, full_path)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/file_serving/base.rb#L44-L80","documentation":"Puppet::FileServing::Base#path= stores a file-serving object's base path and requires it to be absolute, checked with Puppet::FileServing::Base.absolute? (POSIX leading-slash, or drive/UNC form when running on Windows). Any relative path raises ArgumentError. This setter underpins fileserver.conf mounts and metadata construction, so mount points and similar inputs must be absolute.","triggerScenarios":"A fileserver.conf mount whose path is relative (`[extra_files]` + `path files/extra`); Ruby code assigning a relative path to a FileServing object; interpolating a relative setting value into path=.","commonSituations":"Assuming paths resolve relative to puppet.conf or the environment directory; configs ported from tools where relative paths were allowed.","solutions":["Use an absolute path in the mount: `path = /etc/puppetlabs/code/environments/$environment/files/extra`","On Windows use drive-letter (C:\\...) or UNC (\\\\server\\share\\...) absolute paths","When building paths in Ruby, anchor them: File.expand_path(p) or root.join(p)"],"exampleFix":"# fileserver.conf — before\n[extra_files]\n  path files/extra\n# after\n[extra_files]\n  path /etc/puppetlabs/code/environments/$environment/files/extra","handlingStrategy":"validation","validationCode":"def mount_path_ok?(p)\n  Puppet::Util.absolute_path?(p, :posix) || (Puppet::Util::Platform.windows? && Puppet::Util.absolute_path?(p, :windows))\nend\nraise ArgumentError, \"mount path must be absolute: #{p}\" unless mount_path_ok?(p)","typeGuard":"def absolute_mount?(p)\n  p.is_a?(String) && p.start_with?('/') || p.match?(/\\A[a-zA-Z]:[\\\\\\/]/) || p.start_with?('\\\\\\\\')\nend","tryCatchPattern":null,"preventionTips":["Anchor every fileserver.conf mount path at the filesystem root (or use $environment interpolation after an absolute prefix)","In Ruby, run File.expand_path or root.join(p) before assigning to path="],"tags":["puppet","file-serving","path-validation","fileserver-conf","config"],"backgroundTag":"path-must-be-absolute","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}