gohugoio/hugo · critical

publishDir is empty

Error message

publishDir is empty

What it means

A panic in newFs (hugofs/fs.go:101) when publishDir is empty. Hugo requires a concrete output directory to write rendered files; publishDir is sourced from config keys publishDirDynamic then publishDir (default 'public').

Source

Thrown at hugofs/fs.go:101

// NewFromSourceAndDestination creates a new Fs based on the provided Afero Fss
// as the source and destination file systems.
func NewFromSourceAndDestination(source, destination afero.Fs, cfg config.Provider) *Fs {
	workingDir, publishDir := getWorkingPublishDir(cfg)
	return newFs(source, destination, workingDir, publishDir)
}

func getWorkingPublishDir(cfg config.Provider) (string, string) {
	workingDir := cfg.GetString("workingDir")
	publishDir := cfg.GetString("publishDirDynamic")
	if publishDir == "" {
		publishDir = cfg.GetString("publishDir")
	}
	return workingDir, publishDir
}

func newFs(source, destination afero.Fs, workingDir, publishDir string) *Fs {
	if publishDir == "" {
		panic("publishDir is empty")
	}

	if workingDir == "." {
		workingDir = ""
	}

	// Sanity check
	if IsOsFs(source) && len(workingDir) < 2 {
		panic("workingDir is too short")
	}

	// If this does not exist, it will be created later.
	absPublishDir := paths.AbsPathify(workingDir, publishDir)

	pubFs := NewBasePathFs(destination, absPublishDir)

	return &Fs{
		Source:             source,

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Set publishDir in config (Hugo's default is 'public')
  2. When using hugofs.NewFrom, ensure conf.PublishDir is non-empty
  3. Check hugo.toml/command-line flags are not overriding publishDir with ''

Example fix

// before
cfg := config.BaseConfig{WorkingDir: "/proj"}
fs := hugofs.NewFrom(memFs, cfg)
// after
cfg := config.BaseConfig{WorkingDir: "/proj", PublishDir: "public"}
fs := hugofs.NewFrom(memFs, cfg)
Defensive patterns

Strategy: validation

Validate before calling

if publishDir == "" {
    return nil, errors.New("publishDir must be set (default 'public')")
}

Prevention

When it happens

Trigger: Configuring Hugo (or constructing hugofs) with both publishDirDynamic and publishDir unset/empty; calling hugofs.NewFrom with BaseConfig.PublishDir empty.

Common situations: Programmatically building Hugo's config without a publish directory; tests that forget to set PublishDir; a config file blanketing publishDir with an empty string.

Related errors


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