{"record":{"id":"d0a13a037c71ab22","repo":"puppetlabs/puppet","slug":"can-not-create-resource-title-dirname-is-n","errorCode":null,"errorMessage":"Can not create #{@resource.title}; #{dirname} is not a directory","messagePattern":"Can not create #(.+?); #(.+?) is not a directory","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/type/file/ensure.rb","lineNumber":155,"sourceCode":"      end\n      if should == :absent\n        is = property.retrieve\n      else\n        is = :absent\n      end\n\n      property.change_to_s(is, should)\n    end\n\n    # Check that we can actually create anything\n    def check\n      basedir = File.dirname(@resource[:path])\n\n      if !Puppet::FileSystem.exist?(basedir)\n        raise Puppet::Error,\n              \"Can not create #{@resource.title}; parent directory does not exist\"\n      elsif !FileTest.directory?(basedir)\n        raise Puppet::Error,\n              \"Can not create #{@resource.title}; #{dirname} is not a directory\"\n      end\n    end\n\n    # We have to treat :present specially, because it works with any\n    # type of file.\n    def insync?(currentvalue)\n      unless currentvalue == :absent or resource.replace?\n        return true\n      end\n\n      if should == :present\n        !(currentvalue.nil? or currentvalue == :absent)\n      else\n        super(currentvalue)\n      end\n    end\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/type/file/ensure.rb#L137-L173","documentation":"Second branch of ensure#check: the parent path exists but FileTest.directory? is false — a regular file, device, or file-symlink occupies the dirname slot, so no child can be created beneath it and Puppet raises '<title>; <dirname> is not a directory'.","triggerScenarios":"`file { '/etc/app/conf.d/routes.conf': ensure => file }` when /etc/app/conf.d is a plain file; a symlink pointing at a file sitting at the parent path; container images or packages shipping a placeholder file where a directory is expected.","commonSituations":"Name collisions between a file and a needed directory (committed placeholder files); broken symlinks from relocated software; manifests switching a path's role from file to directory without removing the old object.","solutions":["Inspect the parent: `ls -ld <dirname>` to identify the conflicting object.","If it is a stray file, remove it (or manage its removal with a file resource) so the directory can be created.","Manage the parent explicitly as ensure => directory so Puppet converges it before children.","Fix the manifest if the child path was meant to nest elsewhere."],"exampleFix":"// before: /etc/app/conf.d is a regular file on disk\nfile { '/etc/app/conf.d/routes.conf':\n  ensure => file,\n  source => 'puppet:///modules/app/routes.conf',\n}\n\n// after: converge the parent first (remove the stray file once)\nfile { '/etc/app/conf.d': ensure => directory }\n->\nfile { '/etc/app/conf.d/routes.conf':\n  ensure => file,\n  source => 'puppet:///modules/app/routes.conf',\n}","handlingStrategy":"validation","validationCode":"# Ruby pre-flight\nparent = File.dirname(path)\nif File.exist?(parent) && !File.directory?(parent)\n  fail(\"#{parent} exists but is a #{File.ftype(parent)}, not a directory — remove or relocate it\")\nend","typeGuard":null,"tryCatchPattern":"rescue Puppet::Error; on /is not a directory/ lstat the parent path, remove or relocate the conflicting object (or manage it as ensure => absent), then re-run the agent.","preventionTips":["Check ls -ld on the parent before introducing nested resources.","Avoid reusing a path for both a file and a directory role across releases.","Watch for placeholder files committed into image builds.","Manage parents explicitly as ensure => directory."],"tags":["puppet","file","path-conflict","filesystem"],"backgroundTag":"parent-not-a-directory","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}