gohugoio/hugo · error

abort: jekyll root contains neither posts nor drafts

Error message

abort: jekyll root contains neither posts nor drafts

What it means

Returned by `importFromJekyll` after `getJekyllDirInfo` scans the given Jekyll root and finds no `_posts` or `_drafts` directories containing posts. Hugo refuses to proceed because with nothing to import, the specified root is almost certainly wrong, and continuing would create an empty site.

Source

Thrown at commands/import.go:419

	if err != nil {
		return newUserError("path error:", args[0])
	}

	targetDir, err := filepath.Abs(filepath.Clean(args[1]))
	if err != nil {
		return newUserError("path error:", args[1])
	}

	c.r.Println("Import Jekyll from:", jekyllRoot, "to:", targetDir)

	if strings.HasPrefix(filepath.Dir(targetDir), jekyllRoot) {
		return newUserError("abort: target path should not be inside the Jekyll root")
	}

	fs := afero.NewOsFs()
	jekyllPostDirs, hasAnyPost := c.getJekyllDirInfo(fs, jekyllRoot)
	if !hasAnyPost {
		return errors.New("abort: jekyll root contains neither posts nor drafts")
	}

	err = c.createProjectFromJekyll(jekyllRoot, targetDir, jekyllPostDirs)
	if err != nil {
		return newUserError(err)
	}

	c.r.Println("Importing...")

	fileCount := 0
	callback := func(ctx context.Context, path string, fi hugofs.FileMetaInfo) error {
		if fi.IsDir() {
			return nil
		}

		relPath, err := filepath.Rel(jekyllRoot, path)
		if err != nil {
			return newUserError("get rel path error:", path)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Verify the first argument points at the directory that actually contains `_posts` (run `ls <jekyllRoot>` and confirm `_posts` or `_drafts` exists).
  2. If the site lives in a subdirectory (e.g. `docs/`), pass that subdirectory as the Jekyll root.
  3. If posts live only in custom collections, move or symlink them under `_posts` before importing, or migrate those files manually.

Example fix

# before
hugo import jekyll ./myrepo ./newsite
# after (site lives in docs/)
hugo import jekyll ./myrepo/docs ./newsite
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the Jekyll root has posts before invoking import
hasPosts := false
for _, d := range []string{"_posts", "_drafts"} {
    if fi, err := os.Stat(filepath.Join(jekyllRoot, d)); err == nil && fi.IsDir() {
        hasPosts = true
    }
}
if !hasPosts {
    return errors.New("not a Jekyll site root: no _posts or _drafts")
}

Prevention

When it happens

Trigger: `hugo import jekyll <jekyllRoot> <target>` where `jekyllRoot` (or its collections dirs) contains no `_posts`/`_drafts` directories with any files — typically because the wrong path was passed.

Common situations: Pointing the command at the repo root instead of the subdirectory holding the Jekyll site, at the generated `_site` output directory, at a site using only custom collections, or a typo in the path.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/919f3da5aabc9306.json. Report an issue: GitHub ↗.