gohugoio/hugo · error
no filesystem provided
Error message
no filesystem provided
What it means
`loadConfigMain` requires `ConfigSourceDescriptor.Fs` (an afero filesystem) to read config files from. When it is nil, config loading fails fast with this error rather than defaulting to the OS filesystem — Hugo deliberately has no fallback here.
Source
Thrown at config/allconfig/load.go:333
} else {
return strings.Fields(v)
}
default:
return v
}
}
func (l *configLoader) loadConfigMain(d ConfigSourceDescriptor) (config.LoadConfigResult, modules.ModulesConfig, error) {
var res config.LoadConfigResult
if d.Flags != nil {
if err := l.normalizeCfg(d.Flags); err != nil {
return res, l.ModulesConfig, err
}
}
if d.Fs == nil {
return res, l.ModulesConfig, errors.New("no filesystem provided")
}
if d.Flags != nil {
if err := l.applyFlagsOverrides(d.Flags); err != nil {
return res, l.ModulesConfig, err
}
workingDir := filepath.Clean(l.cfg.GetString("workingDir"))
l.BaseConfig = config.BaseConfig{
WorkingDir: workingDir,
ThemesDir: paths.AbsPathify(workingDir, l.cfg.GetString("themesDir")),
}
}
names := d.configFilenames()
if names != nil {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Set the `Fs` field on `ConfigSourceDescriptor`, e.g. `Fs: hugofs.Os` for a real filesystem or `afero.NewMemMapFs()` in tests.
- If using hugolib test helpers, use `hugolib.Test`/siblings, which wire the filesystem for you.
- Trace where the descriptor is constructed and ensure the filesystem is threaded through every call path.
Example fix
// before
res, err := allconfig.LoadConfig(allconfig.ConfigSourceDescriptor{Flags: flags})
// after
res, err := allconfig.LoadConfig(allconfig.ConfigSourceDescriptor{Fs: hugofs.Os, Flags: flags}) Defensive patterns
Strategy: validation
Validate before calling
if d.Fs == nil {
return errors.New("configure a filesystem (e.g. hugofs.NewDefault) before loading config")
} Prevention
- Always populate the Fs field of ConfigSourceDescriptor before calling the loader
- Use a constructor/helper that requires the filesystem as a parameter instead of building the struct literal by hand
- Add a unit test asserting your setup path passes a non-nil afero.Fs
When it happens
Trigger: Programmatic use of `allconfig.LoadConfig` (or `hugolib` deps setup) passing a `ConfigSourceDescriptor` with a nil `Fs` field. Not reachable through the normal `hugo` CLI, which always wires `hugofs.Os`.
Common situations: Embedding Hugo as a library (custom build tools, tests) and forgetting to set `Fs: hugofs.Os` or an `afero.MemMapFs`; refactors that construct the descriptor in a new code path without the filesystem.
Related errors
- failed to create workingDir: %w
- errConfigNotSet
- failed to compile whitelist pattern %q: %w
- failed to load config: %v
- failed to init config: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/65643fee44b58d07.json.
Report an issue: GitHub ↗.