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

  1. Fix the `source` path in the `[dotfiles]` entry to point at an existing file/directory.
  2. Use `mode = "content"` with inline `content` if the file shouldn't be read from disk.
  3. Use `mode = "track"` if this target is only meant to be tracked on the machine, not baked into the image.
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/538d40bfe4ff43b2. Report an issue: GitHub.