jdx/mise · error
dotfile enrollment metadata must be a regular file
Error message
dotfile enrollment metadata must be a regular file
What it means
Manifest::read looks up the enrollment metadata object at a fixed PATH in the history tree and requires it to be stored with git mode 100644 (regular, non-executable file). Any other mode (executable blob, symlink, tree, etc.) is rejected because the manifest must be a plain readable file.
Source
Thrown at src/system/history/manifest.rs:398
}
}
for (path, bits) in &self.permissions {
if *bits > 0o777
|| !super::sync::layout::is_safe_branch_path(path)
|| !self.owns_stream(path)
{
bail!("invalid or unenrolled permission path {path}");
}
}
Ok(())
}
pub(crate) fn read(repo: &HistoryRepo, tree: &str) -> Result<Option<Self>> {
let Some((mode, oid)) = repo.object_at(tree, PATH)? else {
return Ok(None);
};
if mode != "100644" {
bail!("dotfile enrollment metadata must be a regular file");
}
#[derive(Deserialize)]
struct FormatHeader {
format: u64,
}
let bytes = repo.cat_object_bounded(&oid, 4 * 1024 * 1024)?;
let header: FormatHeader = serde_json::from_slice(&bytes)?;
if header.format != 1 {
bail!("unsupported dotfile repository format {}", header.format);
}
let manifest: Self = serde_json::from_slice(&bytes)?;
manifest.validate()?;
Ok(Some(manifest))
}
pub(crate) fn write(&self, repo: &HistoryRepo, tree: &str) -> Result<String> {
self.validate()?;
let oid = repo.hash_blob(&serde_json::to_vec_pretty(self)?)?;View on GitHub (pinned to afd2eddd3a)
Solutions
- Re-commit the metadata object at PATH with mode 100644 (e.g. git hash-object + update-index with the correct mode).
- If the file is a symlink, replace it with a real file and re-write the tree.
- Restore the store from a known-good backup or re-run bootstrap enrollment to rebuild the tree.
Example fix
// before: manifest committed as executable $ git update-index --add --cacheinfo 100755,<oid>,enrollment.json // after $ git update-index --add --cacheinfo 100644,<oid>,enrollment.json
Defensive patterns
Strategy: try-catch
Validate before calling
// inspect the tree entry mode before reading // git ls-tree <tree> <PATH> -> mode should be 100644
Try / catch
match Manifest::read(repo, tree) {
Err(e) if e.to_string().contains("must be a regular file") => {
eprintln!("dotfile store metadata corrupted; re-run bootstrap");
}
other => other?,
} Prevention
- Only modify the history tree with mise's own tooling, not raw git plumbing.
- Never commit the manifest as a symlink or executable.
- Back up the dotfile store before manual surgery.
When it happens
Trigger: Reading the manifest from a history tree where the object at PATH was committed with mode 100755, 120000 (symlink), or 40000 (tree) instead of 100644.
Common situations: Manually rebuilding the history tree with git plumbing (hash-object/mktree) using the wrong mode; a symlinked manifest file committed as a symlink; corruption or tampering with the dotfile store.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid or repeated variant for {}
- [dotfiles]."{}": manifest requires the source to be a direct
- invalid or unenrolled permission path {path}
- the packslip names an executable {:?}, which is not a plain
- {} exists but is not a git checkout with an origin remote
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/348ad911987e2de4.
Report an issue: GitHub.