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
- Verify the first argument points at the directory that actually contains `_posts` (run `ls <jekyllRoot>` and confirm `_posts` or `_drafts` exists).
- If the site lives in a subdirectory (e.g. `docs/`), pass that subdirectory as the Jekyll root.
- 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
- Point the importer at the Jekyll site root (the directory containing _config.yml and _posts), not a subdirectory
- Verify _posts/_drafts exist and are directories, not symlinks to missing targets
- Check that collections-based sites are restructured, since only _posts/_drafts are detected
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
- failed to convert metadata for file %q: %s
- language %q not found
- unsupported format: %q
- deploy not supported in this version of Hugo; install a rele
- target path "%s" exists but is not a directory
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/919f3da5aabc9306.json.
Report an issue: GitHub ↗.