{"record":{"id":"1bde039e9f3133c1","repo":"puppetlabs/puppet","slug":"mounts-without-paths-are-not-usable","errorCode":null,"errorMessage":"Mounts without paths are not usable","messagePattern":"Mounts without paths are not usable","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/file_serving/mount/file.rb","lineNumber":20,"sourceCode":"\nrequire_relative '../../../puppet/file_serving/mount'\n\nclass Puppet::FileServing::Mount::File < Puppet::FileServing::Mount\n  def self.localmap\n    @localmap ||= {\n      \"h\" => Puppet.runtime[:facter].value('networking.hostname'),\n      \"H\" => [\n        Puppet.runtime[:facter].value('networking.hostname'),\n        Puppet.runtime[:facter].value('networking.domain')\n      ].join(\".\"),\n      \"d\" => Puppet.runtime[:facter].value('networking.domain')\n    }\n  end\n\n  def complete_path(relative_path, node)\n    full_path = path(node)\n\n    raise ArgumentError, _(\"Mounts without paths are not usable\") unless full_path\n\n    # If there's no relative path name, then we're serving the mount itself.\n    return full_path unless relative_path\n\n    file = ::File.join(full_path, relative_path)\n\n    unless Puppet::FileSystem.exist?(file) or Puppet::FileSystem.symlink?(file)\n      Puppet.info(_(\"File does not exist or is not accessible: %{file}\") % { file: file })\n      return nil\n    end\n\n    file\n  end\n\n  # Return an instance of the appropriate class.\n  def find(short_file, request)\n    complete_path(short_file, request.node)\n  end","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/file_serving/mount/file.rb#L2-L38","documentation":"At request time, Mount::File#complete_path calls path(node); if the mount never received a `path` line the result is nil, and serving cannot map the client's relative path to a server directory, so ArgumentError is raised. This is the runtime twin of the load-time validate error: it fires when a request actually hits a pathless mount.","triggerScenarios":"A fileserver.conf section like `[data]` containing only allow/deny lines and no `path`, followed by a client requesting `puppet:///data/file.txt`; a path line lost during an edit; expandable paths (%h/%d) that fail to produce a value for the node.","commonSituations":"Copy-pasted mount skeletons never filled in; config edits that accidentally delete the path line; migrations where the data directory path differs per server and one entry was left blank.","solutions":["Add a `path /srv/data` line under the `[data]` section in fileserver.conf","Reload/restart puppetserver (or wait for the config re-read) so the corrected mount takes effect","Note the load-time 'Mounts without paths are not usable' validation should have caught this: if you see the runtime error instead, check for WatchedFile staleness or code paths that bypass Configuration#validate"],"exampleFix":"# before (fileserver.conf)\n[data]\n  allow *.example.com\n\n# after\n[data]\n  path /srv/data\n  allow *.example.com","handlingStrategy":"validation","validationCode":"# Before serving, confirm every mount in fileserver.conf has a path\nsections = Hash.new { |h, k| h[k] = {} }\nFile.readlines(conf).each do |line|\n  if (m = line.match(/\\A\\s*\\[([-\\w]+)\\]/))\n    current = m[1]\n  elsif current && (p = line.match(/\\A\\s*path\\s+(\\S+)/))\n    sections[current][:path] = p[1]\n  end\nend\nmissing = sections.reject { |_, v| v.key?(:path) }.keys","typeGuard":null,"tryCatchPattern":"begin\n  mount.complete_path(relative_path, node)\nrescue ArgumentError => e\n  raise unless e.message == 'Mounts without paths are not usable'\n  fail \"fileserver.conf mount '#{mount.name}' lacks a path line\"\nend","preventionTips":["Always pair a section header with its path line in the same edit","Run a config smoke test (request one file per mount) after changing fileserver.conf","Prefer module serving (puppet:///modules/...) which needs no fileserver.conf"],"tags":["puppet","fileserver","mount","missing-path","argumenterror"],"backgroundTag":"missing-config-value","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}