jdx/mise · error
dotfile enrollment metadata must be a regular file
Error message
dotfile enrollment metadata must be a regular file
What it means
The enrollment metadata object inside the repository tree must be stored as a regular blob with git mode 100644. `read` bails when the object exists at the manifest path but has a different mode (e.g. a symlink, submodule, or executable), because the manifest loader can only safely parse a regular file's contents.
Solutions
- Fix the git mode of the metadata file to 100644 and commit: `git add --chmod=644 <manifest-path>`
- Remove any symlink/submodule at the manifest path and replace it with a regular file containing the manifest contents
- Inspect the tree entry mode (`git ls-tree <tree> <path>`) to confirm what object occupies the manifest path, then repair it
Example fix
// before $ git ls-tree HEAD .history-manifest 100755 blob ... .history-manifest // after git add --chmod=644 .history-manifest && git commit -m "fix manifest mode"
Defensive patterns
Strategy: validation
Validate before calling
let (mode, _oid) = repo.object_at(tree, PATH)
.ok_or("manifest missing")?;
if mode != "100644" { return Err(format!("manifest mode is {mode}, want 100644")); } Try / catch
match Manifest::read(&repo, &tree) {
Err(e) if e.to_string() == "dotfile enrollment metadata must be a regular file" => {
// repair git mode to 100644 and retry
}
other => other,
} Prevention
- Never chmod +x the metadata file or replace it with a symlink before committing
- Check tree entry modes in CI (`git ls-tree`) for the manifest path
- Commit metadata with explicit `git add --chmod=644` in scripts that generate it
When it happens
Trigger: Calling `Manifest::read` against a tree where the manifest path (PATH) resolves to a non-100644 entry — e.g. the metadata file was committed as executable (100755), replaced by a symlink (120000), or turned into a gitlink (160000/submodule).
Common situations: Someone `chmod +x`'d the manifest file before committing; the manifest path was replaced by a symlink; a merge or import tool committed the metadata with the wrong mode; CI writes the manifest via a script that changes its mode.
Related errors
- dotfile enrollment metadata is too large
- Git remote helpers are not supported for remote onboarding
- invalid HTTP setup repository URL; use a Git credential…
- invalid or repeated enrollment path
- invalid or repeated variant for
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/348ad911987e2de4.
Report an issue: GitHub.
Appendix: 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");
}
let bytes = repo.cat_object_bounded(&oid, 4 * 1024 * 1024)?;
Self::from_bytes(&bytes).map(Some)
}
pub(crate) fn read_gix(tree: &gix::Tree<'_>) -> Result<Option<Self>> {
let Some(entry) = tree.lookup_entry_by_path(PATH)? else {
return Ok(None);
};
if entry.mode().value() != 0o100644 {
bail!("dotfile enrollment metadata must be a regular file");
}
if entry.id().header()?.size() > 4 * 1024 * 1024 {
bail!("dotfile enrollment metadata is too large");
}
let object = entry.object()?;
Self::from_bytes(&object.data).map(Some)
}View on GitHub (pinned to 533346cc37)