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

  1. Re-commit the metadata object at PATH with mode 100644 (e.g. git hash-object + update-index with the correct mode).
  2. If the file is a symlink, replace it with a real file and re-write the tree.
  3. 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

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


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