{"record":{"id":"5b93e9c0ea4a3866","repo":"jdx/mise","slug":"dotfiles-source-does-not-exist","errorCode":null,"errorMessage":"[dotfiles].\"{}\": source does not exist: {}","messagePattern":"\\[dotfiles\\]\\.\"(.+?)\": source does not exist: (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/oci/builder.rs","lineNumber":866,"sourceCode":"\nfn resolve_layer_owner(opts_owner: Option<LayerOwner>, oci: &OciConfig) -> LayerOwner {\n    opts_owner.unwrap_or_else(|| {\n        let uid = oci.user_id.unwrap_or(0);\n        let gid = oci.group_id.unwrap_or(uid);\n        LayerOwner::new(uid, gid)\n    })\n}\n\nfn build_dotfiles_layer(\n    cfg: &Config,\n    requests: &[FileRequest],\n    owner: LayerOwner,\n) -> Result<LayerBlob> {\n    let mut entries = DotfilesLayerEntries::default();\n\n    for req in requests {\n        if req.mode != FileMode::Content && !req.source.exists() {\n            bail!(\n                \"[dotfiles].\\\"{}\\\": source does not exist: {}\",\n                req.target_raw,\n                req.source.display()\n            );\n        }\n\n        match req.mode {\n            FileMode::Symlink | FileMode::Copy => {\n                collect_source_as_files(&req.source, &oci_target_path(req)?, &mut entries)\n                    .wrap_err_with(|| {\n                        format!(\"adding [dotfiles].\\\"{}\\\" to OCI image\", req.target_raw)\n                    })?;\n            }\n            FileMode::SymlinkEach => {\n                if !req.source.is_dir() {\n                    bail!(\n                        \"[dotfiles].\\\"{}\\\": mode symlink-each requires a directory source: {}\",\n                        req.target_raw,","sourceCodeStart":848,"sourceCodeEnd":884,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/oci/builder.rs#L848-L884","documentation":"When building an OCI image, `[oci.dotfiles]` entries with mode symlink, copy, or symlink-each copy content from a local source path into the image. Before collecting files, mise verifies that the source path exists; a missing path aborts the build, naming the entry's key and the offending path. Mode 'content' (inline text) is exempt because it has no source file.","triggerScenarios":"A mise.toml `[oci.dotfiles]` entry like `\"~/.gitconfig\" = { source = \"~/.gitconfig\", mode = \"symlink\" }` where the file does not exist on the build machine (tilde not expanded as expected, path typo, or file only present on another host).","commonSituations":"Building images on CI where the dotfile exists only on a developer laptop; typos in relative paths resolved against the project dir; the file genuinely not created yet.","solutions":["Create the source file, or point the entry at a path that exists on the build machine","For machine-independent content, switch to `mode = \"content\"` with inline text instead of a source path","Use absolute paths (and correct tilde handling) for dotfile sources in CI contexts"],"exampleFix":"# before (mise.toml)\n[oci.dotfiles]\n\"~/.gitconfig\" = { source = \"./gitconfig\", mode = \"copy\" }\n# but ./gitconfig does not exist\n\n# after (mise.toml)\n[oci.dotfiles]\n\"/root/.gitconfig\" = { mode = \"content\", content = \"[user]\\n\\tname = CI\\n\" }","handlingStrategy":"validation","validationCode":"python3 - <<'EOF'\nimport tomllib, os, sys\ncfg = tomllib.load(open('mise.toml', 'rb'))\nfor target, spec in (cfg.get('oci', {}).get('dotfiles', {}) or {}).items():\n    mode = spec.get('mode', 'symlink') if isinstance(spec, dict) else 'symlink'\n    src = spec.get('source') if isinstance(spec, dict) else None\n    if mode != 'content' and src and not os.path.exists(os.path.expanduser(src)):\n        sys.exit(f'dotfiles {target!r}: missing source {src}')\nprint('dotfile sources OK')\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for dotfile sources in CI; don't assume the dev's home layout","Prefer mode = \"content\" for small config files to remove filesystem dependencies","Add a pre-build check that every non-content dotfile source exists"],"tags":["oci","dotfiles","build","missing-file","config"],"backgroundTag":"missing-source-file","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}