puppetlabs/puppet · error · ArgumentError

Relative paths must not be fully qualified

Error message

Relative paths must not be fully qualified

What it means

Puppet::FileServing::Base#relative_path= stores a file's path relative to the recursion root and is the mirror of path=: it raises ArgumentError when handed an absolute path (checked with the same absolute? helper). It is set internally while recursively serving directories; custom code that reuses FileServing::Base and passes a full path into relative_path hits this guard.

Source

Thrown at lib/puppet/file_serving/base.rb:72

    @links = value
  end

  # Set our base path.
  attr_reader :path

  def path=(path)
    raise ArgumentError, _("Paths must be fully qualified") unless Puppet::FileServing::Base.absolute?(path)

    @path = path
  end

  # Set a relative path; this is used for recursion, and sets
  # the file's path relative to the initial recursion point.
  attr_reader :relative_path

  def relative_path=(path)
    raise ArgumentError, _("Relative paths must not be fully qualified") if Puppet::FileServing::Base.absolute?(path)

    @relative_path = path
  end

  # Stat our file, using the appropriate link-sensitive method.
  def stat
    @stat_method ||= links == :manage ? :lstat : :stat
    Puppet::FileSystem.send(@stat_method, full_path)
  end

  def to_data_hash
    {
      'path' => @path,
      'relative_path' => @relative_path,
      'links' => @links.to_s
    }
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass only the portion below the recursion root, e.g. 'subdir/file.txt', not '/mnt/root/subdir/file.txt'
  2. Compute it explicitly: Pathname.new(full).relative_path_from(Pathname.new(root)).to_s
  3. If you truly have an absolute location, assign it with path= instead

Example fix

# before
obj.relative_path = '/srv/files/subdir/a.txt'
# after
obj.path = '/srv/files'
obj.relative_path = 'subdir/a.txt'
Defensive patterns

Strategy: validation

Validate before calling

def rel_path(root, full)
  r = Pathname.new(root)
  Pathname.new(full).expand_path.relative_path_from(r.expand_path).to_s
end
obj.relative_path = rel_path('/srv/files', '/srv/files/subdir/a.txt') # => 'subdir/a.txt'

Type guard

def relative_sub_path?(p)
  p.is_a?(String) && !p.empty? && !Puppet::FileServing::Base.absolute?(p)
end

Prevention

When it happens

Trigger: Constructing or monkey-patching file-serving/metadata objects and assigning a fully qualified path to relative_path=; recursion helpers that mix up full_path and the relative offset.

Common situations: Writing custom providers, indirections, or tests that build on Puppet::FileServing::Base; porting logic that computed paths differently.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/be0a896a3d417b82. Report an issue: GitHub.