gohugoio/hugo · error

{createpath} already exists but not a directory

Error message

{createpath} already exists but not a directory

What it means

CreateProject (the `hugo new site` scaffold) requires its createpath to be either absent or a directory. If the path exists but is a regular file, scaffolding cannot proceed because it would need to create directories there.

Source

Thrown at create/skeletons/skeletons.go:99

		"title": "{{ replace .File.ContentBaseName \"-\" \" \" | title }}",
		"date":  "{{ .Date }}",
		"draft": true,
	}

	err = createDefaultArchetype(sourceFs, createpath, defaultArchetype, format)
	if err != nil {
		return err
	}

	return copyFiles(createpath, sourceFs, themeFs)
}

// CreateProject creates a project skeleton.
func CreateProject(createpath string, sourceFs afero.Fs, force bool, format string) error {
	format = strings.ToLower(format)
	if exists, _ := helpers.Exists(createpath, sourceFs); exists {
		if isDir, _ := helpers.IsDir(createpath, sourceFs); !isDir {
			return errors.New(createpath + " already exists but not a directory")
		}

		isEmpty, _ := helpers.IsEmpty(createpath, sourceFs)

		switch {
		case !isEmpty && !force:
			return errors.New(createpath + " already exists and is not empty. See --force.")
		case !isEmpty && force:
			var all []string
			fs.WalkDir(projectFs, ".", func(path string, d fs.DirEntry, err error) error {
				if d.IsDir() && path != "." {
					all = append(all, path)
				}
				return nil
			})
			all = append(all, filepath.Join(createpath, "hugo."+format))
			for _, path := range all {
				if exists, _ := helpers.Exists(path, sourceFs); exists {

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Remove or rename the conflicting file.
  2. Use a different target path that is not a file.

Example fix

// before
hugo new site ./site   # ./site is a file
// after
rm ./site
hugo new site ./site
Defensive patterns

Strategy: validation

Validate before calling

// Ensure createpath is absent or a directory
if fi, err := os.Stat(createpath); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s is a file, not a directory", createpath)
}

Type guard

func isAbsentOrDir(createpath string) bool {
    fi, err := os.Stat(createpath)
    return os.IsNotExist(err) || (err == nil && fi.IsDir())
}

Prevention

When it happens

Trigger: `hugo new site path` where `path` is an existing file (e.g. a file named the same as the requested site).

Common situations: The requested site name collides with an existing file; pointing new site at a path that is already a file.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/4cf9307549a3d53a. Report an issue: GitHub.