jdx/mise · error
[dotfiles]."{req.target_raw}": source does not exist: {req.s
Error message
[dotfiles]."{req.target_raw}": source does not exist: {req.source.display} What it means
When building the dotfiles layer, mise checks that each `[dotfiles]` entry's `source` path exists on disk — unless the mode is `content` or `track`, which don't read the source file (content is inline; track applies only on the tracked machine). If a copy/symlink/template/symlink-each entry points at a missing file or directory, the build fails with the target and source path in the message.
Source
Thrown at src/oci/builder.rs:931
fn resolve_layer_owner(opts_owner: Option<LayerOwner>, oci: &OciConfig) -> LayerOwner {
opts_owner.unwrap_or_else(|| {
let uid = oci.user_id.unwrap_or(0);
let gid = oci.group_id.unwrap_or(uid);
LayerOwner::new(uid, gid)
})
}
fn build_dotfiles_layer(
cfg: &Config,
requests: &[FileRequest],
owner: LayerOwner,
) -> Result<LayerBlob> {
let mut entries = DotfilesLayerEntries::default();
for req in requests {
if !matches!(req.mode, FileMode::Content | FileMode::Track) && !req.source.exists() {
bail!(
"[dotfiles].\"{}\": source does not exist: {}",
req.target_raw,
req.source.display()
);
}
match req.mode {
// a tracked file lives on the machine that tracks it; an image
// has nothing to copy
FileMode::Track => continue,
FileMode::Symlink | FileMode::Copy => {
collect_source_as_files(&req.source, &oci_target_path(req)?, &mut entries)
.wrap_err_with(|| {
format!("adding [dotfiles].\"{}\" to OCI image", req.target_raw)
})?;
}
FileMode::SymlinkEach => {
if !req.source.is_dir() {View on GitHub (pinned to afd2eddd3a)
Solutions
- Fix the `source` path in the `[dotfiles]` entry to point at an existing file/directory.
- Use `mode = "content"` with inline `content` if the file shouldn't be read from disk.
- Use `mode = "track"` if this target is only meant to be tracked on the machine, not baked into the image.
- Create the missing source file, or remove the entry if it's obsolete.
Example fix
# before [dotfiles."/root/.gitconfig"] source = "~/.gitconfig" # missing in build environment mode = "copy" # after [dotfiles."/root/.gitconfig"] mode = "content" content = """ [user]\n email = me@example.com """
Defensive patterns
Strategy: validation
Validate before calling
// before building, check every non-content/track dotfile source exists
for (const req of requests) {
if (!['content', 'track'].includes(req.mode) && !fs.existsSync(req.source)) {
throw new Error(`[dotfiles]."${req.target}": source does not exist: ${req.source}`);
}
} Prevention
- Use absolute or correctly-based paths for `source` values.
- Prefer `mode = "content"` (inline) for files that may not exist on the build machine.
- Keep dotfiles sources inside the repo so they exist wherever the build runs.
- Prune stale `[dotfiles]` entries when files are renamed or deleted.
When it happens
Trigger: A `[dotfiles]."target"` entry with mode `copy`, `symlink`, `symlink-each`, or `template` whose `source` path doesn't exist at build time — deleted file, wrong relative path, or a path that only exists on another machine.
Common situations: Config written on a machine where the dotfile exists but built in a container/CI where it doesn't; renames in the dotfiles repo; source given relative to the wrong base directory; typo in the path.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- [dotfiles]."{}": source does not exist: {}
- [dotfiles]."{}": mode symlink-each requires a directory sour
- [dotfiles]."{}": target is not a safe OCI path
- [dotfiles]: duplicate OCI path {path:?} as both file and dir
- [dotfiles]: duplicate OCI file path {path:?}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/538d40bfe4ff43b2.
Report an issue: GitHub.