Hi! I couldn’t find anything explaining this in docs, only some source code examples that confirm that behavior (1 and 2). I am probably misunderstanding something, so please help me figure this out
In docs for module.mounts there is this note
Adding a new mount to a target root will cause the existing default mount for that root to be ignored. If you still need the default mount, you must explicitly add it along with the new mount.
I started with this config
$ hugo env
hugo v0.151.2+extended+withdeploy darwin/arm64 BuildDate=2025-10-16T16:52:34Z VendorInfo=brew
GOOS="darwin"
GOARCH="arm64"
GOVERSION="go1.25.3"
github.com/sass/libsass="3.6.6"
github.com/webmproject/libwebp="v1.3.2"
$ hugo config mounts
{
"path": "project",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "",
"dir": "/blog/site",
"mounts": [
{
"source": "content",
"target": "content"
},
{
"source": "data",
"target": "data"
},
{
"source": "layouts",
"target": "layouts"
},
{
"source": "i18n",
"target": "i18n"
},
{
"source": "archetypes",
"target": "archetypes"
},
{
"source": "assets",
"target": "assets"
},
{
"source": "static",
"target": "static"
}
]
}
{
"path": "../../theme",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "project",
"dir": "/blog/theme/",
"mounts": [
{
"source": "archetypes",
"target": "archetypes"
},
{
"source": "assets",
"target": "assets"
},
{
"source": "content",
"target": "content"
},
{
"source": "data",
"target": "data"
},
{
"source": "i18n",
"target": "i18n"
},
{
"source": "layouts",
"target": "layouts"
},
{
"source": "static",
"target": "static"
}
]
}
If I update the hugo.toml for the site with custom mount, it behaves exactly as documentation is outlined
+[module]
+ [[module.mounts]]
+ includeFiles = ['[0-9][0-9][0-9][0-9]-*.md']
+ source = '../adrs'
+ target = 'content/adrs'
{
"path": "project",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "",
"dir": "/blog/site",
"mounts": [
{
"source": "../adrs",
"target": "content/adrs"
},
{
"source": "data",
"target": "data"
},
{
"source": "layouts",
"target": "layouts"
},
{
"source": "i18n",
"target": "i18n"
},
{
"source": "archetypes",
"target": "archetypes"
},
{
"source": "assets",
"target": "assets"
},
{
"source": "static",
"target": "static"
}
]
}
{
"path": "../../theme",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "project",
"dir": "/blog/theme/",
"mounts": [
...skipped
]
}
But if I do something similar in hugo.toml for a theme, I get mounts fully replaced with the config, not just the ones that I am overriding.
{
"path": "project",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "",
"dir": "/blog/site",
"mounts": [
...skipped
]
}
{
"path": "../../theme",
"version": "",
"time": "0001-01-01T00:00:00Z",
"owner": "project",
"dir": "/blog/theme/",
"mounts": [
{
"source": "../adrs",
"target": "content/adrs"
}
]
}
I know I can fix this by manually adding all required mounts to a theme’s hugo.toml, but I wanted to understand better why it behaves differently and if this is a bug or works exactly as it should?