gohugoio/hugo · error
failed to save file
Error message
failed to save file %q: %s
What it means
After conversion, the importer writes the new Markdown to `targetFile` via `helpers.WriteToDisk`. This wraps a filesystem write failure for the converted post; `%q` is the source (Jekyll) filename, `%s` the underlying I/O error.
Solutions
- Confirm the target directory exists and is writable (`-w` check).
- Free disk space or move the target to a volume with capacity.
- Re-run the import after correcting permissions on the destination.
- Use an absolute `--target` path under a directory you own.
Example fix
// before // $ hugo import jekyll ~/blog ~/hugo --target=/srv/readonly // after // $ hugo import jekyll ~/blog ~/hugo --target=/home/me/hugo-content
Defensive patterns
Strategy: validation
Validate before calling
// Verify the target directory is writable before importing.
func validateTargetDir(dir string) error {
fi, err := os.Stat(dir)
if err != nil { return err }
if !fi.IsDir() { return fmt.Errorf("%s is not a directory", dir) }
f, err := os.CreateTemp(dir, ".hugoimp-*")
if err != nil { return err }
f.Close(); os.Remove(f.Name())
return nil
} Type guard
null
Try / catch
// On write failure, retry once with a fresh path, then report.
if err := helpers.WriteToDisk(targetFile, r, fs); err != nil {
if errors.Is(err, os.ErrPermission) { /* fix perms / pick new target */ }
} Prevention
- Pass an absolute `--target` under a directory you own.
- Confirm free disk space before large imports.
- Run imports with write access to the destination volume.
When it happens
Trigger: Fires when `WriteToDisk` cannot create/write the target file — destination directory not creatable, out of disk space, permission denied, or a read-only filesystem.
Common situations: Importing into a `--target` directory on a read-only volume; running out of disk during a large import; a target path that conflicts with an existing file marked read-only; CI without write access to the output dir.
Related errors
- abort: jekyll root contains neither posts nor drafts
- data: failed to open
- fileInfo
- is not a directory
- target path " " exists and is not empty
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/bc89f999b3faece9.
Report an issue: GitHub.
Appendix: source
Thrown at commands/import.go:337
return err
}
pf, err := pageparser.ParseFrontMatterAndContent(bytes.NewReader(contentBytes))
if err != nil {
return fmt.Errorf("failed to parse file %q: %s", filename, err)
}
newmetadata, err := c.convertJekyllMetaData(pf.FrontMatter, postName, postDate, draft)
if err != nil {
return fmt.Errorf("failed to convert metadata for file %q: %s", filename, err)
}
content, err := c.convertJekyllContent(newmetadata, string(pf.Content))
if err != nil {
return fmt.Errorf("failed to convert content for file %q: %s", filename, err)
}
fs := hugofs.Os
if err := helpers.WriteToDisk(targetFile, strings.NewReader(content), fs); err != nil {
return fmt.Errorf("failed to save file %q: %s", filename, err)
}
return nil
}
func (c *importCommand) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) {
fs := hugofs.Os
fi, err := fs.Stat(jekyllRoot)
if err != nil {
return err
}
if !fi.IsDir() {
return errors.New(jekyllRoot + " is not a directory")
}
err = os.MkdirAll(dest, fi.Mode())
if err != nil {
return err
}View on GitHub (pinned to 52c9bd7908)